使用LinqKit 動態OR條件查詢
LinqKit 是一套使用Linq時強大的輔助擴充,特別是處理OR條件,因為最近常用到,順便把之前的筆記整理一下,LinqKit 其實網路上也不少人介紹過了,特別推薦的文章放在參考,這邊只記錄程式碼用法。
環境
原始的Product列表
選擇CategoryID為2,4,6,8才顯示
一、使用LinqKit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
void Main()
{
var selectedCategory = new List<int> { 2, 4, 6, 8 };
FilterProducts(selectedCategory).AsEnumerable().Dump();
}
public IQueryable<Products> GetProducts()
{
return Products.AsNoTracking();
}
public IEnumerable<Products> FilterProducts(List<int> selectedCategory)
{
var product = GetProducts();
var predicate = PredicateBuilder.New<Products>();
if (selectedCategory.Count() > 0)
{
foreach (var categoryId in selectedCategory)
{
predicate = predicate.Or(x => x.CategoryID == categoryId);
}
}
return product.Where(predicate);
}
|
二、使用Linq Contains 或 Any等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
void Main()
{
var selectedCategory = new List<int> { 2, 4, 6, 8 };
FilterProducts(selectedCategory).AsEnumerable().Dump();
}
public IQueryable<Products> GetProducts()
{
return Products.AsNoTracking();
}
public IEnumerable<Products> FilterProducts(List<int> selectedCategory)
{
var product = GetProducts();
if (selectedCategory.Count() > 0)
{
product = product.Where(x => selectedCategory.Contains(x.CategoryID.Value));
}
return product;
}
|
可以發現,兩者在SQL語法上,一個是使用OR,一個是使用IN,除此之外結果都是一樣的,看起來使用LinqKit似乎沒有太多的好處,還增加了不少複雜度,但如果現在加上,篩選SupplierID呢,這時候問題就會出現分歧,篩選SupplierID是屬於AND,還是OR呢?
增加Supplier條件
AND情況下
加上一個Where即可解決
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public IEnumerable<Products> FilterProducts(List<int> selectedCategory,int? selectedSupplier = null)
{
var product = GetProducts();
if (selectedCategory.Count() > 0)
{
product = product.Where(x => selectedCategory.Contains(x.CategoryID.Value));
}
if (selectedSupplier != null)
{
product = product.Where(x => x.SupplierID == selectedSupplier);
}
return product;
}
|
OR情況下
這時候就會發現似乎並不那麼簡單,而LinqKit的價值也體現出來了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
void Main()
{
var selectedCategory = new List<int> { 2, 4, 6, 8 };
// 為了方便呈現OR改成8
int selectedSupplier = 8;
FilterProducts(selectedCategory,selectedSupplier).AsEnumerable().Dump();
}
public IQueryable<Products> GetProducts()
{
return Products.AsNoTracking();
}
public IEnumerable<Products> FilterProducts(List<int> selectedCategory,int? selectedSupplier = null)
{
var product = GetProducts();
var predicate = PredicateBuilder.New<Products>();
if (selectedCategory.Count() > 0)
{
foreach (var categoryId in selectedCategory)
{
predicate = predicate.Or(x => x.CategoryID == categoryId);
}
}
var predicateSupplier = PredicateBuilder.New<Products>();
if (selectedSupplier != null)
{
predicateSupplier = predicateSupplier.Or(x => x.SupplierID == selectedSupplier);
}
// 兩者串接起來
predicateSupplier = predicateSupplier.Or(predicate);
return product.Where(predicateSupplier);
}
|
參考
搞搞就懂 使用 LINQKit PredicateBuilder 解決動態OR條件查詢窘境
https://dotblogs.com.tw/wasichris/2014/12/20/147734
LINQKit Github
https://github.com/scottksmith95/LINQKit