实体框架AddOrUpdate实现

时间:2015-05-31 23:37:40

标签: c# linq entity-framework linq-to-entities

我正在尝试创建类似于AddOrUdpate的扩展方法。

用法应该是这样的:

var student = context.Students.GetOrCreate(
    s => s.Name, 
    new Student() { Name = "SomeName" })

如果有任何具有该名称的用户,则应将其返回,否则应创建新用户。

这就是我所拥有的:

public static TEntity GetOrCreate<TEntity>(
    this IDbSet<TEntity> set,
    Expression<Func<TEntity, object>> identifierExpression,
    TEntity entity) where TEntity : class
{
    var func = identifierExpression.Compile();
    var id = func.Invoke(entity);
    var persistedEntity = set.FirstOrDefault(e => func.Invoke(e) == id);

    if (persistedEntity != null)
    {
        return persistedEntity;
    }

    return set.Add(entity);
}

但我无法使用LINQ to Entities调用invoke 我该如何使用identifierExpresion

1 个答案:

答案 0 :(得分:1)

使用它创建一个可以传递给FirstOrDefault的新表达式,让EF提供程序处理将表达式转换为SQL。新表达式将测试与从编译和调用的表达式中检索到的id的相等性。像这样:

var equalityExpr = Expression.Equal(identifierExpression.Body, Expression.Constant(id));
var findMatchExpr = Expression.Lambda<Func<TEntity, bool>>(equalityExpr, identifierExpression.Parameters);
var persistedEntity = set.FirstOrDefault(findMatchExpr);