我创建了一个通用扩展方法,只有在指定的键不存在时才添加新实体。 这适用于数据库中的数据,但我还想检查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
答案 0 :(得分:2)
这是因为dbSet.Local
没有实现IQueryable<T>
。 IEnumerable<T>
的LINQ扩展只接受委托,而不是表示那些的表达式。
有两种方法可以解决这个问题:
使用Compile()
方法将lambda表达式编译为委托,并将其用于本地查询。
生成的代码应如下所示:
var Exists = dbSet.Local.SingleOrDefault(lamba.Compile());
通过在IQueryable<T>
实施中调用AsQueryable()
来包装本地集合。
生成的代码应如下所示:
var Exists = dbSet.Local.AsQueryable().SingleOrDefault(lamba);