码迷,mamicode.com
首页 > Windows程序 > 详细

《C#本质论》读书笔记(15)使用查询表达式的LINQ

时间:2016-11-21 12:05:51      阅读:422      评论:0      收藏:0      [点我收藏+]

标签:rand   pattern   解释   search   att   min   class   vol   catch   

15.1 查询表达式的概念 

15.1.1 投射
15.1.2 筛选
15.1.3 排序
15.1.4 let子句
15.1.5 分组
15.1.6 使用into进行查询延续
15.1.7 用多个from子句“平整”序列的序列

15.2 查询表达式作为方法调用



简单的查询表达式
  1. private static void ShowContextualKeywords1()  
  2. {  
  3.     IEnumerable<string> selection = from word in Keywords  
  4.                                     where !word.Contains(‘*‘)  
  5.                                     select word;  
  6.   
  7.     foreach (string keyword in selection)  
  8.     {  
  9.         Console.Write(" " + keyword);  
  10.     }  
  11. }  
  12.   
  13. private static string[] Keywords = {  
  14.                                        "abstract""add*""alias*""as""ascending*""base",  
  15.                                        "bool""break""by*""byte""case""catch""char",  
  16.                                        "checked""class""const""continue""decimal",  
  17.                                        "default""delegate""descending*""do""double",  
  18.                                        "dynamic*""else""enum""event""equals*",  
  19.                                        "explicit""extern""false""finally""fixed",  
  20.                                        "from*""float""for""foreach""get*""global*",  
  21.                                        "group*""goto""if""implicit""in""int",  
  22.                                        "into*""interface""internal""is""lock""long",  
  23.                                        "join*""let*""namespace""new""null""object",  
  24.                                        "on*""operator""orderby*""out""override",  
  25.                                        "params""partial*""private""protected""public",  
  26.                                        "readonly""ref""remove*""return""sbyte""sealed",  
  27.                                        "select*""set*""short""sizeof""stackalloc",  
  28.                                        "static""string""struct""switch""this""throw",  
  29.                                        "true""try""typeof""uint""ulong""unchecked",  
  30.                                        "unsafe""ushort""using""value*""var*""virtual",  
  31.                                        "void""volatile""where*""while""yield*"  
  32.                                    };  
技术分享

 15.1.1 投射
       查询表达式输出是一个IEnumerbale<T>IQueryable<T>集合。T数据类型是从select或者groupby子句推导。
       上例string数据类型是从 select word 推导的,因为word是一个字符串。word数据类型是由from子句所指定的IEnumerbale<T>集合的类型参数(这里是Keywords)。由于Keywords是一个string数组,它实现了IEnumerbale<T>,所以word是一个字符串。
        表达式查询特定类型集合时,结果允许将数据投射成一个完全不同的类型。
Directory.GetCurrentDirectory()  
技术分享
  1. public static void Main()  
  2.  {  
  3.      List1(Directory.GetCurrentDirectory(),"*");  
  4.  }  
  5.   
  6.  static void List1(string rootDirectory, string searchPattern)  
  7.  {  
  8.      IEnumerable<FileInfo> files =  
  9.          from fileName in Directory.GetFiles(  
  10.              rootDirectory, searchPattern)  
  11.          select new FileInfo(fileName);  
  12.   
  13.      foreach (FileInfo file in files)  
  14.      {  
  15.          Console.WriteLine(".{0} ({1})",  
  16.              file.Name, file.LastWriteTime);  
  17.      }  
  18.  }  
 
技术分享
 这里返回的是一个IEnumerable<FileInfo>,而不是System.IO.Directory.GetFiles()返回的IEnumerables<string>数据类型。
 技术分享
 
C#3.0引入匿名类型,很大程度上就是利用像这样的“投射”功能。
  1. var files =    
  2. from fileName in Directory.GetFiles(    
  3.     rootDirectory, searchPattern)    
  4. select new FileInfo(fileName);    

15.1.2 筛选
where子句在垂直方向筛选集合。
  1.     IEnumerable<string> selection = from word in Keywords  
  2.                                     where !word.Contains(‘*‘)  
  3.                                     select word;  

15.1.3 排序
在查询表达式中对数据进行排序的是 orderby 子句。
  1. IEnumerable<string> fileNames =  
  2.     from fileName in Directory.GetFiles(  
  3.         rootDirectory, searchPattern)  
  4.     orderby (new FileInfo(fileName)).Length descending,  
  5.         fileName  
  6.     select fileName;  

ascending和descending是上下文关键字,分别是升序或降序排序。

15.1.4 let子句
下面代码与上面的代码相似。问题是FileInfo要创建两次,分别在orderby 和 select子句中创建。
  1. public static void Main()  
  2. {  
  3.     ListByFileSize2(Directory.GetCurrentDirectory(), "*");  
  4. }  
  5.   
  6. static void ListByFileSize2(  
  7.         string rootDirectory, string searchPattern)  
  8. {  
  9.     IEnumerable<FileInfo> files =  
  10.         from fileName in Directory.GetFiles(  
  11.             rootDirectory, searchPattern)  
  12.         orderby new FileInfo(fileName).Length, fileName  
  13.         select new FileInfo(fileName);  
  14.   
  15.     foreach (FileInfo file in files)  
  16.     {  
  17.         //  As simplification, current directory is  
  18.         //  assumed to be a subdirectory of  
  19.         //  rootDirectory  
  20.         string relativePath = file.FullName.Substring(  
  21.             Environment.CurrentDirectory.Length);  
  22.         Console.WriteLine(".{0}({1})",  
  23.             relativePath, file.Length);  
  24.     }  
  25. }  

可以用let子句避免这种昂贵的开销。
  1. IEnumerable<FileInfo> files =  
  2.                 from fileName in Directory.GetFiles(  
  3.                     rootDirectory, searchPattern)  
  4.                 let file = new FileInfo(fileName)  
  5.                 orderby file.Length, fileName  
  6.                 select file;  

let 解释

  1. let子句引入了一个新的范围变量
  2. 它容纳的表达式值可以在查询表达式剩余部分使用
  3. 可以添加任意数量的let表达式,只需要它们每一个作为一个附加的子句
  4. 放在第一个from子句之后,最后一个select/group by子句之前,加入查询即可

15.1.5 分组
SQL中涉及对数据项进行聚合以生成一个汇总或合计或其他聚合值。
LINQ中表达力更强,LINQ允许将单独的项分组到一系列子集合中,还允许那些组与所查的集合中项关联
  1. private static void GroupKeywords1()  
  2. {  
  3.     IEnumerable<IGrouping<boolstring>> selection =  
  4.         from word in keyWords  
  5.         group word by word.Contains(‘*‘);  
  6.   
  7.     foreach (IGrouping<boolstring> wordGroup  
  8.         in selection)  
  9.     {  
  10.         Console.WriteLine(Environment.NewLine + "{0}:",  
  11.             wordGroup.Key ?  
  12.                 "Contextual Keywords" : "Keywords");  
  13.         foreach (string keyword in wordGroup)  
  14.         {  
  15.             Console.Write(" " +  
  16.                 (wordGroup.Key ?  
  17.                     keyword.Replace("*"null) : keyword));  
  18.         }  
  19.     }  
  20. }  

技术分享
 
结果 :
技术分享

 查询结果是一系列IGrouping<bool,?string>类型元素。
 技术分享
查询生成一系列分组,将相同的bool类型键应用于组内的每个string。


在group子句后面选择一个匿名类型
  1. private static void GroupKeywords1()  
  2. {  
  3.     IEnumerable<IGrouping<boolstring>> keywordGroups =  
  4.         from word in keyWords  
  5.         group word by word.Contains(‘*‘);  
  6.   
  7.     var selection = from groups in keywordGroups  
  8.                     select new  
  9.                     {  
  10.                         IsContextualKeyword = groups.Key,  
  11.                         Items = groups  
  12.                     };  
  13.   
  14.     foreach (var wordGroup in selection)  
  15.     {  
  16.         Console.WriteLine(Environment.NewLine + "{0}:",  
  17.             wordGroup.IsContextualKeyword ?  
  18.                 "Contextual Keywords" : "Keywords");  
  19.         foreach (var keyword in wordGroup.Items)  
  20.         {  
  21.             Console.Write(" " +  
  22.                 keyword.Replace("*"null));  
  23.         }  
  24.     }  
  25. }  

技术分享
 IGrouping<TKey,TElement>.Key 重命名为IsContextualKeyword,并命名了子集合属性Items。有人人为可以在匿名类型中添加一个属性来标识数据项的个数,然后,这个功能由wordGroup.Items.Count()提供。

15.1.6 使用into进行查询延续





































《C#本质论》读书笔记(15)使用查询表达式的LINQ

标签:rand   pattern   解释   search   att   min   class   vol   catch   

原文地址:http://www.cnblogs.com/tangge/p/6084871.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!