我有很多实体是由EF针对现有数据库生成的。这些实体中的大多数都具有“名称”属性。我想要一个方法,它接受泛型类型的表达式,并传入一个字符串值,最终将与底层实体的name属性进行比较。
到目前为止,我有这样的事情:
T SpecialLookup(DbSet<T> dbSet, Func<T, string, bool> exp, string specialParam)
where T: class, new() {
//here we can do something with specialParam first like clean it up.
//now pass in the specialParam to the underlying query which can
//ultimately look up a matching object by "name == specialParam".
var predicate = PredicateBuilder.New<T>(x => exp(x, specialParam));
var obj = dbSet.AsExpandable().SingleOrDefault(predicate);
return obj;
}
这里的想法是,我可以调用查找函数并传入一个特殊值,并使用特殊值作为参数在DbSet上调用委托。
SpecialLookup(dbContext.SomeEntities,
delegate(SomeEntity obj, string name) {
return obj.name == name;
},
" special"
);
我在这里使用LinkqKit尝试使这项工作,但我收到错误“无法将FieldExpression转换为LambdaExpression”。
我的第一个问题是:是否有更好/更简单的方法来实现这一目标?我这太复杂了吗?我甚至需要使用LinqKit吗?
第二:我怎样才能克服这个错误?
答案 0 :(得分:0)
这几乎就像你使用linq重写linq扩展。如上所述,如果您已经写出了X和Y场景以及您希望实现的目标,那将会很有帮助。我个人知道,当我想要这样的东西时,我已经使用了表达式:
private List<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>>
predicate = null) where TEntity : class
{
using (var context = new ExpensesEntities())
{
IQueryable<TEntity> data = context.Set<TEntity>();
if (predicate != null)
{
data = data.Where(predicate);
}
return data.ToList();
}
}
当我有一个存储库模式时,我使用了这个,我有两个不同的表(在实例中更多)。我想把上下文部分包装起来为我自动调用dispose(using(var context = new Context()))并且只处理问题的内容。这本质上是哪个表以及我想要运行谓词的属性。因此,在下面的示例中,我将如何为所有表调用此函数,然后为另一个表在TypeId的属性上为其添加谓词。
public List<X> GetCategories() => GetEntities<X>();
public List<Y> GetTypes() => GetEntities<Y>(x => x.TypeID != 3);