【问题标题】:Get items by matching predicate method通过匹配谓词方法获取项目
【发布时间】:2016-03-31 20:04:21
【问题描述】:

我正在尝试使用谓词实现一个通用方法。 我写了一些代码:

public ICollection<T> GetProductsByMatching<T>(Expression<Func<T, bool>> predicate)
{
    return context.Products.Where(predicate).Include("ShopPlace, Images").ProjectTo<T>().ToList();
}

以及这个方法的用法:

var a = service.GetProductsByMatching<ProductInfo>(x => x.Name.StartsWith("value") 
        || x.Price < 150);

最后我有Invalid Operation Exception类型“System.Linq.Queryable”上没有通用方法“Where”与提供的类型参数和参数兼容。

我的代码有什么问题?感谢您的提前!

【问题讨论】:

  • 因为T != Product。这段代码应该做什么?你的意思是打电话给context.Set&lt;T&gt;吗?
  • @CodeCaster 通过谓词从数据库中获取产品并将其映射到 ProductInfo(ViewModel 类)
  • 是的,that 部分在代码中很明显,但我想首先找出您输入Expression&lt;Func&lt;T, bool&gt;&gt; 的原因。在我的回答中,我现在根据方法名称做了一些假设。

标签: c# entity-framework linq


【解决方案1】:

context.Products.Where(predicate) 中的谓词显然只能是Expression&lt;Func&lt;Product, bool&gt;&gt;,而不是Expression&lt;Func&lt;T, bool&gt;&gt;,因为不能保证TProduct

您正在尝试过滤目标类型的谓词,而过滤必须发生在源类型上:

public ICollection<T> GetProductsByMatching<T>(Expression<Func<Product, bool>> predicate)
{
    return context.Products.Where(predicate)
                           .Include("ShopPlace, Images")
                           .ProjectTo<T>()
                           .ToList();

}

【讨论】:

  • 我怀疑是这样。但我不想在方法使用范围内链接到Product 类。是否可以编写通过ProductInfo字段过滤产品的函数?
  • 这是一个完全不同的问题。您不能使用 ProductInfo 来执行此操作(因为该类与 Product 没有任何关系,并且可能包含您的 Product 不包含的属性,因此您的表达式无法转换为数据库中不存在的列)。您可以添加一个接口层,消费者在该接口上查询,然后将该接口应用于您的实体模型。
  • 如果我确定相同的属性,是否有任何方法可以将基于 ProductInfo 类的源谓词转换/修改/映射到 Product 类。我的意思是保存表达式的主体,但将谓词转换为另一种类型。
  • 这也是一个完全不同的问题。参见例如How do I translate an expression tree of one type to a different expression type?
猜你喜欢
  • 1970-01-01
  • 2012-03-22
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 2014-07-26
  • 2012-05-19
  • 1970-01-01
相关资源
最近更新 更多