我有许多实体是由 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 吗?
第二:如何克服此错误?
这几乎就像你在使用 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();
}
}
当我有一个存储库模式时,我使用了它,其中我有两个不同的表(在实际示例中更多(。 我想将上下文部分包装起来以自动为我调用处置(using(var context = new Context((((并处理问题的实质。 这本质上是哪个表以及我想在其上运行谓词的属性。 因此,在下面的示例中,我将如何仅为所有表调用它,然后为另一个表在 TypeId 的属性上向其添加谓词。
public List<X> GetCategories() => GetEntities<X>();
public List<Y> GetTypes() => GetEntities<Y>(x => x.TypeID != 3);