我想知道将实体条件存储在参数中的最可维护的方法(如果存在),以便在每个 linq where 条件中重用它。
假设有一个 Product 实体:
public class Product
{
public bool IsDiscontinued { get; set; }
public int UnitsInStock { get; set; }
}
我想向 Product 类添加一个属性 IsOnSale,其中包含确定产品是否促销的逻辑。
在这个简单的例子中,逻辑可以是:
IsOnSale = IsDiscontinued == false && UnitsInStock > 0
那么我应该能够编写这种类型的 linq 查询:
from p in context.Products
where p.IsOnSale == true
select p
解决方案的目的应该是,如果将来确定产品是否在销售的逻辑发生变化(例如添加属性 IsBackOrderAllowed),我不必在任何地方编辑 linq 查询,而只需更改 IsOnSale 属性。
此处发布了类似的问题,但似乎解决了更具体的问题。
I'd like to know the most maintainable way (if exists) to store an entity condition in a parameter so to reuse it in every linq where conditions.
Suppose to have a Product entity:
public class Product
{
public bool IsDiscontinued { get; set; }
public int UnitsInStock { get; set; }
}
I'd like to add to the Product class a property IsOnSale that contains the logic to determine whether the product is on sale or not.
In this simple example the logic could be:
IsOnSale = IsDiscontinued == false && UnitsInStock > 0
Then I should be able to write a linq query of this type:
from p in context.Products
where p.IsOnSale == true
select p
The purpose of the solution should be that, if in the future the logic to determine whether the product is on sale or not changes (e.g. adding a property IsBackOrderAllowed), I don't have to edit the linq queries everywhere but simply have to change the IsOnSale property.
A similar question has been posted here but seems to address a more specific problem.
发布评论
评论(4)
您可以创建一个方法,返回按您的条件过滤的 IQueryable:
并且您可以像这样使用它:
如果您想使用像 Yakimych 的答案中那样的表达式来执行此操作,那么这将起作用:
:
并且您可以像这样使用它 重要的是它被声明为表达式,否则实体框架将无法将其转换为 SQL,因为 lambda 将被编译为 IL 而不是表达式树。
You could make a method that returns an IQueryable filtered by your conditions:
and you would use it like this:
If you want to do it with an expression like in Yakimych's answer then this would work:
and you could use it like so:
It is important that it is declared as an expression, otherwise Entity Framework won't be able to translate it into SQL because the lambda will be compiled into IL instead of an Expression Tree.
你可以做这样的事情:
然后在你的查询中你做:
更新
作为与@DoctaJonez评论讨论的结果 - 使用这种方法的过滤将在客户端执行(是或当然效率低下),因此应使用
Expression>
而不是Func
。You can do something like this:
Then in your query you do:
Update
As a result of the comment-discussion with @DoctaJonez - the filtering with such an approach will be performed on the client-side (which is or course inefficient), thus
Expression<Func<Product, bool>>
should be used instead ofFunc<Product,bool>
.这里的第一个问题是 linq to 实体无法使用不属于模型的属性(= 它无法使用自定义属性)。
您必须定义表达式。如果您仅定义
Func
,它将作为 Linq to 对象执行:现在您必须以这种方式调用查询:
另一种方法是使用 模型定义函数。
First problem here is that linq to entities cannot work with properties which are not part of the model (= it can't work with custom properties).
You must define expression. If you define only
Func
it will be executed as Linq to objects:Now you must call the query this way:
Another approach is using model defined function.
我认为您正在寻找规范模式。
有关将其与 EF 一起使用(包含基本实现)的文章,请访问 http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/ 。
如何实现这一点的一个示例是进行查询
并使用以下帮助程序和规范定义。
您还可以使用此模式做更多事情,所以我建议您研究一下!
I think you are looking for the Specification Pattern.
An article on using it with EF that includes a base implementation is available at http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/ .
An example of how to implement this would be to make your query
and to use the following helper and specification definition.
You can do a lot more with this pattern too, so I suggest looking into it!