0

我有许多由 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 吗?

第二:我怎样才能克服这个错误?

4

1 回答 1

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);
于 2018-01-15T23:51:38.490 回答