繁体   English   中英

动态 FirstOrDefault 谓词表达式

[英]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'AmbrosioExpressionHelper 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM