我有一个必需的业务逻辑,应从PriceList
表中获取产品价格。您可以在代码中看到查询的某些部分重复出现。
我很关心如何重用查询的某些部分:例如p.Sellers.Any(s => s.PersonId == personID)
或currentDate >= p.StartDate && currentDate <= p.EndDate
。
var basicQuery = context.PriceList.Where(p => !p.Deleted);
// first search by product, salesman and date
var priceItem = basicQuery.FirstOrDefault(p => p.ProductId == productID &&
p.Sellers.Any(s => s.PersonId == personID) &&
currentDate >= p.StartDate &&
currentDate <= p.EndDate);
if(priceItem != null)
return priceItem;
priceItem = basicQuery.FirstOrDefault(p => p.ProductId == productID &&
currentDate >= p.StartDate &&
currentDate <= p.EndDate);
if(priceItem != null)
return priceItem;
priceItem = basicQuery.FirstOrDefault(p => p.ProductId == productID &&
p.Sellers.Any(s => s.PersonId == personID));
if(priceItem != null)
return priceItem;
priceItem = basicQuery.FirstOrDefault(p => p.ProductId == productID);
return priceItem;
答案 0 :(得分:5)
由于您的示例中所有条件都与AND连接 - 您可以像这样重复使用它们:
Expression<Func<Price,bool>> sellerFilter =
(p) => p.Sellers.Any(s => s.PersonId == personID);
Expression<Func<Price,bool>> dateFilter =
(p) => currentDate >= p.StartDate && currentDate <= p.EndDate;
var priceItem = basicQuery
.Where(sellerFilter)
.Where(dateFilter)
.Where(p => p.ProductId == productId)
.FirstOrDefault(); //etc
如果你的条件比一连串的AND更复杂 - 那将会更加棘手。
答案 1 :(得分:2)
我首先将p.ProductId == productID
推入basicQuery
,因为它是所有四种变体中连词的一部分:
var basicQuery = context.PriceList.Where(p => !p.Deleted && p.ProductId == productID);
之后我会创建两个表达式 - 按卖家和日期:
Expression<Func<Product,bool>> bySeller = p =>
p.Sellers.Any(s => s.PersonId == personID);
Expression<Func<Product,bool>> byDate = p =>
currentDate >= p.StartDate && currentDate <= p.EndDate);
现在,您可以在Where
子句
var priceItem = basicQuery.Where(bySeller).Where(byDate).FirstOrDefault();
if (priceItem != null) return priceItem;
var priceItem = basicQuery.Where(byDate).FirstOrDefault();
if (priceItem != null) return priceItem;
var priceItem = basicQuery.Where(bySeller).FirstOrDefault();
return basicQuery.FirstOrDefault();
或使用null coalesce删除if
s:
return basicQuery.Where(bySeller).Where(byDate).FirstOrDefault()
?? basicQuery.Where(byDate).FirstOrDefault()
?? basicQuery.Where(bySeller).FirstOrDefault()
?? basicQuery.FirstOrDefault();