我想知道在参数中存储实体条件的最易维护的方法(如果存在),以便在每个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属性。
类似的问题也发布在here上,但似乎解决了一个更具体的问题。
发布于 2011-03-16 18:39:44
您可以创建一个方法,该方法返回根据您的条件过滤的IQueryable:
public IQueryable<Product> WhereOnSale(this IQueryable<Product> source)
{
return source.Where(p => p.IsDiscontinued == false && p.UnitsInStock > 0);
}你可以这样使用它:
from p in context.Products.WhereOnSale()
select p如果你想用Yakimych的答案中的表达式来做这件事,那么这是可行的:
Expression<Func<Product, bool>> isOnSale =
(p => p.IsDiscontinued == false && p.UnitsInStock > 0);你可以这样使用它:
context.Products.Where(isOnSale)重要的是要将其声明为表达式,否则实体框架将无法将其转换为SQL,因为lambda将被编译为IL而不是表达式树。
发布于 2011-03-16 18:36:16
你可以这样做:
Func<Product, bool> isOnSaleFunc =
(p => p.IsDiscontinued == false && p.UnitsInStock > 0);然后在您的查询中执行以下操作:
context.Products.Where(isOnSaleFunc)更新
由于评论-与@DoctaJonez的讨论-这种方法的过滤将在客户端执行(这是或过程低效的),因此应该使用Expression<Func<Product, bool>>而不是Func<Product,bool>。
发布于 2011-03-16 18:46:23
这里的第一个问题是linq to entities不能处理不属于模型的属性(=它不能处理自定义属性)。
您必须定义表达式。如果你只定义了Func,它将作为Linq对象来执行:
public class Product
{
...
public static Expression<Func<Product, bool>> IsOnSale
{
get
{
return p => (p.IsDiscontinued == false && p.UnitsInStock > 0);
}
}
}现在您必须这样调用查询:
var query = context.Products.Where(Product.IsOnSale);另一种方法是使用model defined function。
https://stackoverflow.com/questions/5323959
复制相似问题