最近写Linq碰到一个问题,
就是如果要写一个查询系统,这个系统里面有很多TextBox可以填,
然后捞出符合各个字段的数据。
在SQL查询的时候还满方便的,用字符串连连连就可以了,
( 也就是sqlStr += "or name like '%sanc%' " )
那在Linq的话呢,就完全没有办法可以用连连连的方法QQ
后来和GOOGLE祷告后,GOOGLE告诉我目前有三种方法可以处理。
第一是出自MS的Linq Dynamic Query
Library
但听说一堆问题,就懒得去试了。
第二是自己写表达式树,也就是建立QueryBuilder
好吧,我有空会再找时间研究看看QB
第三则是由有名的C# In a Nutshell作者写的一个Library
( 其实满想读他写的书的,但是全英文....光看这篇,就懒了=
= )
总之,最后用了第三个方案,因为真的很方便,也很直觉。
要扩充或是移除,都很方便。
他给的第一个范例是这样,这个范例没用到什么技巧,
反正直接就可以用了。
1 2 3 4 5 6 7 8 9 10 11 |
IQueryable SearchProducts (params string[] keywords) { IQueryable query = dataContext.Products; foreach (string keyword in keywords) { string temp = keyword; query = query.Where (p => p.Description.Contains } return query; } |
这个的功能很简单,假设你送进去,"可乐"、"畅快",
他就会把在Products的Description(描述)里面有"可乐"和"畅快"这两个关键词
的内容捞出来,也就是用and的方法。
但是,我们常常需要用到or方法,例如要查询"可乐"、"雪碧"。
那在用这种查询方法,就没办法查的到了....
( 不可能会出现一种可乐是雪碧口味的吧= =)
ok~所以作者提出了另外一种方法,也就是使用了PredicateBuilder
1 2 3 4 5 6 7 8 9 10 11 |
IQueryable SearchProducts (params string[] keywords) { var predicate = PredicateBuilder.False(); foreach (string keyword in keywords) { string temp = keyword; predicate = predicate.Or (p } return dataContext.Products.Where (predicate); } |
用Or方法,就可以用or来查询"可乐"和"雪碧"。
赞吧!!果然是神人级的。
但是看到这边,不要马上贴上去使用阿~@@~
因为最重要最重要的关键是
我们还没有PredicateBuilder这个类别阿。
这里有两个方法可以使用这个类别。
一、去作者网站下载LinqKit
二、去作者网站将PredicateBuilder的程序代码复制贴上
( 两个都够简单吧= = )
最后,要补充一下,
如果是使用Linq to Entity的话,要把程序代码的最后一行改为
1 |
return objectContext.Products.AsExpandable().Where |
也就是如下程序代码。
1 2 3 4 5 6 7 8 9 10 11 |
IQueryable SearchProducts (params string[] keywords) { var predicate = PredicateBuilder.False(); foreach (string keyword in keywords) { string temp = keyword; predicate = predicate.Or (p } return objectContext.Products.AsExpandable().Where (predicate); } |
另外,如果要查名子、描述、发行公司等等
很多TextBox的话,怎么办呢?
就改成这样。
1 2 3 4 |
var predicate = PredicateBuilder.False(); predicate = predicate.Or(p => p.name.Contains(要查询的)); predicate = predicate.Or(p => p.Description.Contains objectContext.Products.AsExpandable().Where |
这样扩充有没有很容易呢!?
最后,这些我都还没实验过,实验完后,我会再修改这篇文章,
将正确的讯息贴上。