创建用于查询实体框架的泛型表达式



我有许多实体是由 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);

最新更新