[英]Create dynamic LINQ expression for Select with FirstOrDefault inside
[英]Dynamic FirstOrDefault Predicate expression
我基本上想在 collections 中概括 EF Core 删除处理。 我已经编写了下面的方法,但是我无法根据传递的键名动态地构造谓词。 在多对多关系的情况下,键是复合键,例如(UserId,RoleId),因此没有可以从基础 class 使用的专用主键。 方法是:
public static void InsertUpdateOrDeleteCollection<T>(this ICollection<T> dbVersion, ICollection<T> localVersion, string keyName) where T : IObjectWithState
{
// If I have passed keyName = DeptId, this can give me L.H.S i.e p => p.DeptId
Expression<Func<T, object>> pkFieldExpression = ExpressionHelper.ConstructLambda<T>(keyName);
// I dont't know how to get R.H.S i.e objForeach.Dept
// and combine both ofcourse to be served in FirstOfDefault(...)
foreach (var localVersionItem in localVersion)
{
var dbVersionItem = dbVersion.FirstOrDefault(f => f.keyName == localVersionItem.keyName); // <= This is my problem!
if (dbVersionItem == null)
dbVersion.Add(localVersionItem);
else
dbVersionItem.UpdateItem(localVersionItem);
}
foreach (var dbVersionItem in dbVersion)
{
if (!localVersion.Any(a.keyName == dbVersionItem.keyName)) // <= And this too!
dbVersionItem.TrackingState = TrackingStates.Deleted;
}
}
所以,基本上我想基于 foreach 迭代 object 键和 object 的键动态构造谓词,必须在其上进行 FirstOrDefault 。 键名作为字符串参数传递。
dbVersion.FirstOrDefault(predicate == value of iteration object);
更新:找到解决方案并在下面添加了答案。
好的,我让它工作了。 我已经在使用Julián Andrés D'Ambrosio的ExpressionHelper class 了。 通过使用此 class 中的一些方法,我添加了一个新方法:
public static Func<T, bool> GenerateComparePredicate<T>(T entity, string propertyName)
{
var keyProperty = entity.GetType().GetProperties().FirstOrDefault(prop => (string)prop.Name == propertyName);
var keyPropertyValue = keyProperty.GetValue(entity);
var compareExpression = GetCriteriaWhere<T>(propertyName, OperationExpression.Equals, keyPropertyValue);
return compareExpression.Compile();
}
然后将我的方法更新为:
public static void InsertUpdateOrDeleteCollection<T>(this ICollection<T> dbVersion, ICollection<T> localVersion, string keyName) where T : IObjectWithState
{
foreach (var localVersionItem in localVersion)
{
Func<T, bool> predicateCompare = ExpressionHelper.GenerateComparePredicate(localVersionItem, keyName);
var dbVersionItem = dbVersion.FirstOrDefault(predicateCompare);
if (dbVersionItem == null)
dbVersion.Add(localVersionItem);
else
dbVersionItem.UpdateItem(localVersionItem);
}
foreach (var dbVersionItem in dbVersion)
{
Func<T, bool> predicateCompare = ExpressionHelper.GenerateComparePredicate(dbVersionItem, keyName);
if (!localVersion.Any(predicateCompare))
dbVersionItem.TrackingState = TrackingStates.Deleted;
}
}
现在像魅力一样工作!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.