EF扩展AddIfNotExists本地lamba

时间:2014-06-12 11:25:34

标签: c# entity-framework extension-methods

我创建了一个通用扩展方法,只有在指定的键不存在时才添加新实体。 这适用于数据库中的数据,但我还想检查Local值。可能它已添加但尚未保存到数据库中。 我使用以下代码:

public static void AddIfNotExists<TEntity>(this IDbSet<TEntity> set, Expression<Func<TEntity, object>> identifierexp, params TEntity[] entities) where TEntity : class
    {
        if (set == null)
            throw new Exception("DbSet not assinged");
        if (entities == null)
            throw new Exception("Entities not assinged");

        var dbSet = set as DbSet<TEntity>;

        if (dbSet != null)
        {
            MemberExpression body = identifierexp.Body as MemberExpression;

            if (body == null)
            {
                UnaryExpression ubody = (UnaryExpression)identifierexp.Body;
                body = ubody.Operand as MemberExpression;
            }


            ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "X");
            Expression property = Expression.Property(parameter, body.Member.Name);

            foreach (var entity in entities)
            {
                Expression target = Expression.Constant(entity.GetType().GetProperty(body.Member.Name).GetValue(entity).ToString());
                Expression containsMethod = Expression.Call(property, "Contains", null, target);
                Expression<Func<TEntity, bool>> lamba = Expression.Lambda<Func<TEntity, bool>>(containsMethod, parameter);

                var Exists = dbSet.SingleOrDefault(lamba);


                if (Exists == null)
                {
                    dbSet.Add(entity);
                }

            }

        }

    }

当我使用以下代码更改它时,他无法在本地属性上使用Lamba。因为不是正确的超载。但据我所知,过载是一样的。什么是正确的方法?

                var Exists = dbSet.Local.SingleOrDefault(lamba);
                if (Exists != null)
                    return;

                Exists = dbSet.SingleOrDefault(lamba);
                if (Exists != null)
                    return;

                dbSet.Add(entity);

我得到的错误:

Error   1   'System.Collections.ObjectModel.ObservableCollection<TEntity>' does not contain a definition for 'SingleOrDefault' and the best extension method overload 'System.Linq.Enumerable.SingleOrDefault<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,bool>)' has some invalid arguments  

1 个答案:

答案 0 :(得分:2)

这是因为dbSet.Local没有实现IQueryable<T>IEnumerable<T>的LINQ扩展只接受委托,而不是表示那些的表达式。

有两种方法可以解决这个问题:

  1. 使用Compile()方法将lambda表达式编译为委托,并将其用于本地查询。 生成的代码应如下所示:

    var Exists = dbSet.Local.SingleOrDefault(lamba.Compile());
    
  2. 通过在IQueryable<T>实施中调用AsQueryable()来包装本地集合。 生成的代码应如下所示:

    var Exists = dbSet.Local.AsQueryable().SingleOrDefault(lamba);