【问题标题】:EF extension AddIfNotExists local lambaEF 扩展 AddIfNotExists 本地羔羊
【发布时间】:2014-06-12 11:25:33
【问题描述】:

我创建了一个通用扩展方法,仅当指定键不存在时才添加新实体。 这适用于数据库中的数据,但我也想检查本地值。可能它已经被添加并且还没有保存到数据库中。 我使用以下代码:

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  

【问题讨论】:

  • Expression&lt;Func&lt;&gt;&gt;Func&lt;&gt; 不同。如果您查看 Local,它采用的是委托 (Func) 而不是表达式树 (Expression>)

标签: c# entity-framework extension-methods


【解决方案1】:

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

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

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

    var Exists = dbSet.Local.SingleOrDefault(lamba.Compile());
    
  2. 通过在其上调用 AsQueryable() 将本地集合包装在 IQueryable&lt;T&gt; 实现中。 生成的代码应如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多