【发布时间】:2019-06-06 18:12:56
【问题描述】:
这是根据条件将这些 linq/lambda 语句连接在一起的最佳方式吗?这样我就不必多次参与同一件事。
我不是专家,但似乎有一些冗余?也许执行路径不是最有效的! 例如。
var products = context.Products.Select(c => c);
if (input.DefendantId != null)
{
products =
from p in products
join pd in context.ProductDefendant
on p.Id equals pd.ProductId
where pd.DefendantId == input.DefendantId
select p;
}
if (input.DefendantCode != null && input.DefendantId == null)
{
products =
from p in products
join pd in context.ProductDefendant
on p.Id equals pd.ProductId
join d in context.Defendants
on pd.DefendantId equals d.Id
where d.DefendantCode.Any(rp => EF.Functions.Like(d.DefendantCode, "%" + input.DefendantCode + "%"))
select p;
}
if (input.ProductId != null)
{
products = products.Where(c => c.Id == input.ProductId);
}
if (input.ProductName != null && input.ProductId == null)
{
products = products.Where(c => EF.Functions.Like(c.ProductName, "%" + input.ProductName + "%"));
}
var productsVM =
from p in products
join pd in context.ProductDefendant
on p.Id equals pd.ProductId
join d in context.Defendants
on pd.DefendantId equals d.Id
select new GetProductsReturnViewModel
{
Id = p.Id,
ProductName = p.ProductName,
DefendantCode = d.DefendantCode
};
switch (input.SortBy + "_" + input.OrderBy)
{
case "productName_DESC":
productsVM = productsVM.OrderByDescending(c => c.ProductName);
break;
default:
productsVM = productsVM.OrderBy(c => c.ProductName);
break;
}
if (input.PageSize != 0)
{
productsVM = productsVM.Skip((input.Page - 1) * input.PageSize).Take(input.PageSize);
}
return productsVM;
【问题讨论】:
-
上部的半连接似乎可以从内部查询中移出。除此之外,它看起来确实不错。如果 GetProductsReturnViewModel 不是模型的一部分,您可以考虑缓存它们。
-
我认为我遇到的问题是,当我有 input.DefendantCode != null && input.DefendantId == null 的条件并且使用该部分时 where 子句很好,但是随后如果使用条件 input.ProductName != null && input.ProductId == null ,则 where 子句将被覆盖。所以基本上如果两个条件都满足,我需要两个 where 子句,目前只使用一个。我只能看输出窗口,看看正在运行什么 sql
-
如何覆盖该子句?应用于过滤的 IQueryable 的 where 应导致包含两个条件(AND 连接)的 IQueryable
标签: c# entity-framework linq lambda