c# - EF 扩展 AddIfNotExists 本地 lambda

标签 c# entity-framework lambda extension-methods

我制作了一个通用扩展方法,仅当指定键不存在时才添加新实体。 这适用于数据库中的数据,但我还想检查本地值。也许它已被添加但尚未保存到数据库中。 我使用以下代码:

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);
                }

            }

        }

    }

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

                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  

最佳答案

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

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

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

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

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

关于c# - EF 扩展 AddIfNotExists 本地 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24183168/

相关文章:

java - 在日期属性为字符串的列表中查找具有最大日期的对象

C# 随机不变

c# - MySQL 时区支持

带有 WCF Web 服务的 C# 传统服务器

c# - asp.net: 无效的回发或回调参数

entity-framework - Entity Framework 分离一个实体和相关实体消失

c++ - 捕获破坏了我的 lambda 函数

c# - Entity Framework : Foreign Key in code first

c# - 无法转换类型为 'System.Data.Objects.MaterializedDataRecord' 的对象

c# - 动态生成属性表达式和空参数