*LINQ
//简单的查询表达式:与SQL类似,但是稍有区别。
static string[] KeyWords = {"abstract","add*","alisa*","as","ascending","base","enum","new*","……"};
private static void ShowContextualKeyWorlds()
{
IEnumerable<string> selection = from word in KeyWords
where !word.Contains('*')
select word;
foreach (string keyword in selection)
{ Console.Write(" "+keyword); }
}
**投射:查询表达式输出的是一个IEnumrable<T>或IQueryable<T>集合。T的数据类型是从select 或groupby子句推到的。用表达式来查询一个它特定类型的集合时,结果并非一定是原始类型,而select子句允许子句将数据投射程一个完全不同的类型。
例如:
IEnumrable<FileInfo> files=from fileName in Directory.GetFiles(roofDirectory,searchPattrn)
=select new FileInfo(fileName);
**在查询表达式中使用匿名类型:好处,执行一个查询时,不是获取全部数据,而是通过匿名类型,只在集合中获取或存取需要的数据。
static void Lists2(string rootDirectory, string searchPattern)
{
var files =
from fileName in Directory.GetFiles(rootDirectory, searchPattern)
select new
{
Name=fileName,
LastWriteTime=File.GetLastWriteTimeUtc(fileName)
};
foreach (var file in files)
{
Console.WriteLine("{0}{1}",file.Name,file.LastWriteTime);
}
}
*查询表达式和推迟执行:和之前在集合中讲过的类似,只有在遍历或访问到集合的数据项的时候才会执行与数据型相关的操作,这就是推迟执行,比如,上述中selection赋值操作仅仅是赋值,where的条件判断还没有执行。修改上述代码如下:
static string[] KeyWords = {"abstract","add*","alisa*","as","ascending","base","enum","new*","……"};
private static void ShowContextualKeyWorlds()
{
Console.WriteLine("1:");
IEnumerable<string> selection = from word in KeyWords
where !word.Contains('*')
select word;
Console.WriteLine("2:");
foreach (string keyword in selection)
{
Console.WriteLine("3:");
Console.WriteLine(" "+keyword); }
}
输出的结果如下://根据结果可以分析得到selection仅仅赋值保存,而没有直接执行。是在遍历集合的项时才执行。
1:
2:
3:
abstract
3:
as
3:
ascending
3:
base
3:
enum
3:
……
*筛选
where子句在“垂直”方向上筛选集合,筛选条件使用一个断言来表示的,所谓断言,本质上就是返回布尔值的一个lamda表达式。
static void Lists2(string rootDirectory, string searchPattern)
{
var files =
from fileName in Directory.GetFiles(rootDirectory, searchPattern)
//where 子句筛选。
where File.GetLastWriteTime(fileName)<DateTime.Now.AddMinutes(-1)
select new FileInfo(fileName);
foreach (FileInfo file in files)
{
string relativePath = file.FullName.Substring(Environment.CurrentDirectory.Length);
Console.WriteLine("{0}{1}",file.Name,file.LastWriteTime);
}
}
*排序:ascending ,descending 关键字,使用orderby
orderby (new FileInfo(fileName)).Length descending.fileName //先按照文件名的长度降序排序,然后按文件名的升序排序。
**let子句:用let避免多余的实例化
IEnumerable<FileIno> files=form fileName in Directory.GetFiles(rootDirectory ,searchPattern)
orderby new FileInfo(fileName).Length,fileName
select new FileInfo(fileName);
form fileName in Directory.GetFiles(rootDirectory ,searchPattern)
let file =new FileInfo(fileName) //用let避免多余的实例化
orderby file.Length,fileName
select file;
**分组
c#中除了提供与每个分组有关的聚合信息,查询表达式还允许组内单独的项构成一个系列子集合,父列表中的每个项都对应这样的一个子集合。
static string[] KeyWords = { "*abstract", "add*", "alisa*", "as", "ascending", "base", "enum", "new*", "……" };
private static void keyWords1()
{
//1.IGrouping<TKey,TElement>的类型参数是由Group和by后面的数据类型类决定的。
IEnumerable<IGrouping<bool, string>> selection =
from word in KeyWords
//1.1TElement之所以是一个string,是因为word是一个string类型,Tkey的类型由by后面的数据类型那个来决定。
group word by word.Contains('*');
//2.它允许我们返回一个嵌套的foreach循环。
//2.1首先用foreach()来遍历selection,打印出关键字的类型作为标题。
foreach (IGrouping<bool, string> wordGroup in selection)
{
Console.WriteLine(Environment.NewLine + "{0}", wordGroup.Key ? "Contextual Keywords" : "Keyword");
//2.2遍历selection中的每个wordGroup,并打印出每个关键字
foreach (string keyword in wordGroup)
{
Console.Write(" " + (wordGroup.Key?keyword.Replace("*",null):keyword));
}
}
//3.可以在groupby子句的后面附加一个select子句,从而实现投射功能。
//从广义上说,select子句是通过“查询延续”机制来附加的---任何查询主题都可以附加到其他查询主体的后面,这称为“查询延续”(query econtinuation)
}
//在groupby 后面使用匿名类型
IEnumerable<IGrouping<bool, string>> keywordGroups =
from word in KeyWords
group word by word.Contains('*');
//在groupby 后面选择一个匿名类型。
var selection = from groups in keywordGroups
select new
{
IsContextualKeyWord = groups.Key,
Items = groups
};
foreach(var wordgroup in selection)
{
Console.WriteLine(Environment.NewLine + "{0}" + "\t the total count {1}",
wordgroup.IsContextualKeyWord ? "Contextual Keywords" : "Keyword", wordgroup.Items.Count());
foreach (var keyword in wordgroup.Items)
{
Console.Write(" " + (wordgroup.IsContextualKeyWord ? keyword.Replace("*", null) : keyword));
}
}
**使用into进行延续查询
var selection =
from word in KeyWords
group word by word.Contains('*')
//使用into在现在查询结果上运行附加的查询,是所有查询表达式的一个功能。
//这段代码等价于前一段代码,但是into可以作为一个管道运算符使用,将一个查询的结果作为同第二个查询的结果合并到一起。
into groups
select new
{
IsContextualKeyWord = groups.Key,
Items = groups
};
**实现隐式执行
将选择条件保存到selection中,而不是在赋值的时候执行查询,这个功能是通过委托来实现的。
***查询表达式作为方法调用
IEnumerable<string> selection=from word in Keywords
where word.Contains('*')
select word;
========>>>>>等价于=============>>>>>>>
IEnumerable<sting> selection=
Keywords.Where(word=>word.Contains(‘*’));