Linq实践系列:一句代码实现DataTable全文搜索(Full Text Search)
话说某项目需要在客户端执行全文搜索,包括多条件和部分匹配。开发一个新功能首先得google,像这样的代码外国同行早就给我们准备好了,没想到竟然落空。Google不成就只能开发了,我一看有个实习的小伙,那就你了,开发这个功能,顺便练习一下Linq。他写了半天代码也没写出来,只好写了个传统的代码交差(见后面)。于是我就写了下面的代码:
public static List<DataRow> FullTextSearch(this DataTable dataTable, string[] keywords)
{
var q = dataTable.AsEnumerable().Where<DataRow>(row => keywords.All(key => row.ItemArray.Select(p => p.ToString()).Any<string>(s => s.Contains(key))));
return q.ToList();
}
例如 下面是出生婴儿的DataTable
|
序号 |
姓名 |
出生日期 |
性别 |
医院 |
|
1 |
李韦 |
2012-07-10 |
男 |
解放军总医院 |
|
2 |
云岚 |
2012-07-10 |
女 |
朝阳妇幼医院 |
|
3 |
周玲 |
2012-07-10 |
女 |
海淀医院 |
|
4 |
于晴 |
2012-08-10 |
女 |
北京军区总医院 |
|
5 |
王凌 |
2012-09-10 |
男 |
协和医院 |
|
6 |
张玉 |
2012-10-10 |
男 |
中日友好医院 |
现在我们要搜索2012年出生北京军区医院姓 "于"的小朋友,那搜索的关键字可以是:2012 军区 于
string[] keywords = new string[]{"2012", "军区", "于"};
dataTable.FullTextSearch(keywords);
搜索的结果如下:
|
4 |
于晴 |
2012-08-10 |
女 |
北京军区总医院 |
有了这个扩展方法,我们就可以搜索各种各样的DataTable了,能满足基本的需求了。但这一句代码对于Linq的新手来说,其实还是挺长的,分解开说:
Where:要从所有的记录里找出满足下面条件的
All:所有的关键字都要满足下面的条件
Any:记录中的任何一项包含关键字
综合起来说就是,我们要从一个表找出这样的记录,所有的关键字都包含在记录的任意项里了。其实Linq也没有什么特别神奇的,只不过是把一些循环语句和条件语句封装成函数式。看习惯了有声明式编程的感觉,比命令式的风格更容易看懂。
public static List<DataRow> FullTextSearch(this DataTable dataTable, string keywords)
{
List<DataRow> row = new List<DataRow>();
DataTable dt = new DataTable();
string[] keywordToArray = keywords.Split(' ');
List<string> collectionID = new List<string>();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
DataRow dr = dataTable.Rows[i];
int flag = 0;
foreach (var key in keywordToArray)
{
for (int j = 0; j < dr.ItemArray.Length; j++)
{
if (dr[j].ToString().Contains(key))
{
flag = flag + 1;
break;
}
}
}
if (flag == keywordToArray.Length)
row.Add(dataTable.Rows[i]);
}
return row;
}

浙公网安备 33010602011771号