我正在尝试在控制器中生成一个过滤列表以传递给MVC视图。
我知道我可以在SQL中执行此操作:(我在某种程度上缩短了SQL ...)
SELECT ItemID, Item, SupplierID, Supplier, BrandID, Brand, CategoryID, Category, SubCategoryID, SubCategory, TypeID, Type
FROM Table1 join Table 2... etc
WHERE (supplierid = @SID OR @SID = -99) AND
(brandid = @BID OR @BID = -99) AND
(categoryid = @CID OR @CID = -99) AND ....
但是我想知道用C#和它做的最佳方法。 Linq(或者如果最好根据上面的内容调用存储过程并使用它)
这是我的控制器的开始:
public async Task<ActionResult> Index(int? supplierid, int? itembrandid, int? categoryid, int? subcategoryid, int? itemtypeid)
{
List<DTOClasses.ItemsListDTO> items = new List<DTOClasses.ItemsListDTO>();
items = await (from i in db.Items
join b in db.ItemBrand on i.BrandID equals b.BrandID
join s in db.Suppliers on b.SupplierID equals s.SupplierID
join sc in db.SubCategories on i.SubCategoryID equals sc.SubCategoryID
join c in db.Categories on sc.CategoryID equals c.CategoryID
where // get stuck at this point
select new DTOClasses.ItemsListDTO
{
ItemId = i.ItemID
//etc..
}
).ToListAsync();
return View(items);
}
我希望尽可能避免编写可能的25个嵌套if语句。
**编辑
例如,为了保持linq查询干净整洁,让输入参数的每个组合与他们自己的查询一起执行。 if( BID != null && SID != null && CID != null)
{ query 1}
else
if (BID != null && SID != null && CID == null)
{query 2}
答案 0 :(得分:0)
使用空合并运算符??
,C#与COALESCE相当,但我不确定这与您的问题有何关联。 C#还具有与AND和OR在一起的多个条件的完全等价,所以就像SQL一样:
items = await (from i in db.Items
join b in db.ItemBrand on i.BrandID equals b.BrandID
join s in db.Suppliers on b.SupplierID equals s.SupplierID
join sc in db.SubCategories on i.SubCategoryID equals sc.SubCategoryID
join c in db.Categories on sc.CategoryID equals c.CategoryID
where ((b.BrandID == BID || BID == -99) &&
(s.SupplierID == SID || SID == -99) &&
(sc.CategoryID == CID || CID == -99))
select new DTOClasses.ItemsListDTO
{
ItemId = i.ItemID
//etc..
}
).ToListAsync();
如果重复性对你的影响和我一样多,你可以将其隐藏在辅助扩展方法中,但是假设所有ID类型的幻数保持相同-99(并且忽略了使用幻数的错误程度)实际上是)。
static class IDExt {
static bool IDMatches(this int anID, int testID) => testID == anID || testID == -99;
}
然后你有
where b.BrandID.IDMatches(BID) && s.SupplierID.IDMatches(SID) && sc.CategoryID.IDMatches(SID)