对于Linq查询有几个要点,数据源,元素,投影。把握这几个要点,那么运用起来得心应手。
(一)查找句子
这里指的句是是英文句子,英文句子以.!?结束(逗点,叹号,问号)。下面摘取《The Call of the Wild》一段来进行介绍。
先来一大段:
string str=@"There he lay for the remainder of the weary night, nursing his wrath"+
@"and wounded pride. He could not understand what it all meant. What"+
@"did they want with him, these strange men? Why were they keeping"+
@"him pent up in this narrow crate? He did not know why, but he felt"+
@"oppressed by the vague sense of impending calamity. Several times"+
@"during the night he sprang to his feet when the shed door rattled open,"+
@"expecting to see the Judge, or the boys at least. But each time it was"+
@"the bulging face of the saloon-keeper that peered in at him by the sickly"+
@"light of a tallow candle. And each time the joyful bark that trembled in"+
@"Buck's throat was twisted into a savage growl.";
然后,查找带有“Buck”的句子,并分别打印出来。
首先,这里的数据源就是这个字符串(或者说这个段落),然后元素就是想要的每个句子,投影也是句子,就是要段落中的所有句子。
获取数据源:数据源应该是句子集合,对于字符串来说,直接的进行Linq查询,那么它的元素将是一个一个的字符,所以这里要得到数据源:
string[] sentences=str.Split(new char[]{'.','?','!'});
用来分隔句子。现在的结果是:
There he lay for the remainder of the weary night, nursing his wrathand wounded pride
He could not understand what it all meant
Whatdid they want with him, these strange men
Why were they keepinghim pent up in this narrow crate
He did not know why, but he feltoppressed by the vague sense of impending calamity
Several timesduring the night he sprang to his feet when the shed door rattled open,
expecting to see the Judge, or the boys at least
But each time it wasthe bulging face of the saloon-keeper that peered in at
him by the sicklylight of a tallow candle
And each time the joyful bark that trembled inBuck's throat was twisted into a savage growl
然后,对于含有“Buck”的句子就是其中的元素,它的类型是字符串;而所需要就是这些句子。
var q1=from p in sentences
where p.Contains("Buck")
select p;
And each time the joyful bark that trembled inBuck's throat was twisted into a savage growl
上边查出的句子前边有空格,现在去除空格,这里用正则表达式来完成。
这个相对比较简单:
var q1=from p in sentences
where p.Contains("Buck")
select Regex.Replace(p,@"^\ ","");
And each time the joyful bark that trembled inBuck's throat was twisted
into a savage growl
(二)遍历文件
遍历目录下的所有文件并打印:
DirectoryInfo path = new DirectoryInfo(@"L:\css");
FileInfo[] fileinfos = path.GetFiles();
var q = from p in fileinfos
elect new { 文件名 = p.Name, 文件大小 = p.Length / 1024 };
q.Dump();
我现在打印的是目录下的文件:
文件名
文件大小
1.jpg
247
float.htm
0
……
……
链接.htm
0
上边只是遍历了目录下的文件,而对于其中的文件夹中的文件没能查询到,下边实现遍历全路径,方法很简单:
DirectoryInfo path = new DirectoryInfo(@"L:\css");
FileInfo[] fileinfos = path.GetFiles("*", SearchOption.AllDirectories);
var q = from p in fileinfos
select new
{ 文件名 = p.Name, 文件大小 = p.Length / 1024, 文件路径 = p.FullName };
q.Dump();
文件名
文件大小
文件路径
1.jpg
247
L:\css\1.jpg
float.htm
0
L:\css\float.htm
……
……
……
qq.gif
25
L:\css\pic\qq.gif
t.png
15
L:\css\pic\t.png
找到数据源,明确其中的元素单位,并按所需进行投影设置。
(三)查找最大的文件
按文件大小排序,并通过元素选择来得到文件
DirectoryInfo path = new DirectoryInfo(@"L:\css");
FileInfo[] fileinfos = path.GetFiles("*", SearchOption.AllDirectories);
var q = (from p in fileinfos
orderby p.Length
select p).Last();
Console.Write(q.FullName);
(四)在文本文件中查找字符串
查找带有指定字符串的文件
var q = from p in fileinfos
where p.Extension == ".htm"
select p.FullName;
先指定筛选条件文件文件,扩展名为htm的文件,然后投影选择文件全名。然后在投影之前添加对文本文件中的字符串的查找:
DirectoryInfo path = new DirectoryInfo(@"L:\css");
FileInfo[] files = path.GetFiles("*", SearchOption.AllDirectories);
var q = from p in files
where p.Extension == ".htm"
&& GetFileContent(p.FullName).Contains("导航")
select p;
foreach (var info in q)
Console.WriteLine(info.FullName);
GetFileContent方法是通过路径读取文本文件内容。
结果略。
这里提一下let关键字。Let类似mssql中的declare,用于声明局部变量
var q = from p in files
where p.Extension == ".htm"
let strContent= GetFileContent(p.FullName)
where strContent.Contains("导航")
select p;
这里设置strContent变量,然后再通过另一个where来与上过滤条件。Let非常有用。