我该如何重用where条件

时间:2017-07-21 12:12:20

标签: c# entity-framework

我有一个必需的业务逻辑,应从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;

2 个答案:

答案 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();