久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

LINQ標(biāo)準(zhǔn)查詢操作符詳解

 ThinkTank_引擎 2017-06-27

一,、 關(guān)于LINQ 

      LINQ 英文全稱是“Language-Integrated Query”,,中文為“語言集成查詢”,它是微軟首席架構(gòu)師,、Delphi 之父和C# 之父——Anders Hejlsberg 提出的并由其團(tuán)隊著力打造的一組用于c#和Visual BasiC語言的擴(kuò)展,,為 C# 和 Visual Basic 語言語法提供強大的查詢功能。微軟從2003年開始啟動LINQ的開發(fā),,在VisualStudio2008中開始加入LINQ功能,。

      LINQ提供的便利:

      1)使用一種簡化的方式編寫查詢語句;

      2)通過消除運行時錯誤和捕捉編譯時錯誤減少開發(fā)時間,;

      3)直接在開發(fā)語言中提供對LINQ的IntelliSense和調(diào)試支持,;

      4)消除關(guān)系數(shù)據(jù)和面向?qū)ο箝_發(fā)之間的障礙;

      5)提供與數(shù)據(jù)源無關(guān)的統(tǒng)一查詢語法,。

      LINQ的一大特性是可以對多種數(shù)據(jù)源查詢,,而且查詢的語法相同,這為開發(fā)人員處理不同的數(shù)據(jù)源的數(shù)據(jù)提供了極大的便利,。

      LINQ 能查詢的數(shù)據(jù)有但不限于:

      1)對象,,LINQ to Objects。比如集合,、數(shù)組,、字符串等等,。

      2)關(guān)系數(shù)據(jù),分為 LINQ to DataSet 和 LINQ to SQL,,前者用于 DataSet 查詢,,后者用于 SQL Server 數(shù)據(jù)庫查詢。

      3)XML,,LINQ to XML,。

 

      二、 操作符和LINQ 

 
      下面代碼演示從一個字符串?dāng)?shù)組中獲取所有以“t”結(jié)尾的字符串,,并打印,。
 

string[] fruits = new string[]
                                 {
                                     "Apple""Apricot""Arbutus""Banana""Bennet""Betelnut""Betelnut",
                                     "Black brin"
                                 };
            IEnumerable<string> val = from fruit in fruits where fruit.EndsWith("s") select fruit;
            foreach (string s in val)
            {
                Console.WriteLine(s + "\n");
            }

   

      這是一個簡單的LINQ表達(dá)式,其中where和select是LINQ眾多標(biāo)準(zhǔn)查詢操作符中的兩個,,select是投影操作符,,它在某個系列(即實現(xiàn)了Ienumerable<string>接口的對象上)上進(jìn)行投影,where是限制操作符類型,,類似我們sql語句中的where,,用于過濾某個系列。局部變量fs實現(xiàn)了具有遍歷功能的Ienumerable<string>接口,。LINQ中提供了很多和where,、select這樣的標(biāo)準(zhǔn)查詢操作符,這些查詢操作符提供了很多功能,,如過濾,、排序、分組,、聚合,、轉(zhuǎn)換等功能,LINQ包括兩個標(biāo)準(zhǔn)查詢操作符集合,,一個集合用于操作IEnumerable<T>類型的對象,,另外一個集合則是用于操作IQueryable<T>類型的對象。這些操作符由Enumerable和Queryable類的靜態(tài)方法組成,。如Enumerable類提供了Select,、Where等查詢操作符的靜態(tài)方法,更詳細(xì)的了解,,可以查閱MSDN,,網(wǎng)址:http://msdn.microsoft.com/zh-cn/library/bb341635.aspx
       
       可能有部分讀者看了Enumerable和Queryable類提供了的靜態(tài)方法,,如Enumerable類中提供了where的方法為:

     

 public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

 

      在觀照from fruit in fruits where fruit.EndsWith("t") select fruit這樣的查詢表達(dá)式會有些疑惑,,因為我們通常使用靜態(tài)方法都是這樣用的:方法名.靜態(tài)方法(方法參數(shù)),但是在上面查詢表達(dá)式中,,這些靜態(tài)方法卻被當(dāng)做關(guān)鍵字的方式來使用,。其實LINQ提供了查詢語法和方法語法這兩種語法來編寫查詢功能,,像上面是查詢語法,實現(xiàn)var fs = from fruit in fruits where fruit.EndsWith("t") select fruit這樣的查詢功能,,我們還可以用LINQ提供的方法語法來實現(xiàn):
var fs = fruits.where(f=>f.EndsWith(“t”));


     可見在方法語法使用標(biāo)準(zhǔn)查詢操作符和Enumerable類提供的靜態(tài)方法是吻合的,。寫過T-SQL語句的讀者對于LINQ的查詢語法都很容易理解和閱讀,這是人容易理解的方式,,但其實CLR并不理解查詢語法,CLR能夠理解方法語法,,因此編譯一個LINQ的查詢表達(dá)式時,,查詢語法將會被轉(zhuǎn)換為方法語法。

 

      三,、 LINQ操作符類型類型


      可根據(jù)標(biāo)準(zhǔn)查詢操作符的操作“類型”進(jìn)行分類,,如把它們分成投影、限制,、排序,、聯(lián)接、分組,、串聯(lián),、聚合、集合,、生成,、轉(zhuǎn)換、元素,、相等,、量詞、分割等,。


類型 操作符名稱
投影操作符 Select,SelectMany
限制操作符 Where
排序操作符 OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse
聯(lián)接操作符 Join,GroupJoin
分組操作符 GroupBy
串聯(lián)操作符 Concat
聚合操作符 Aggregate,Average,Count,LongCount,Max,Min,Sum
集合操作符 Distinct,Union,Intersect,Except
生成操作符 Empty,Range,Repeat
轉(zhuǎn)換操作符 AsEnumerable,Cast,OfType,ToArray,ToDictionary,ToList,ToLookup
元素操作符 DefaultIfEmpty,ElementAt,ElementAtOrDefault,First,Last,FirstOrDefault, LastOrDefault,Single,SingleOrDefault
相等操作符 SequenceEqual
量詞操作符 All,Any,Contains
分割操作符 Skip,SkipWhile,Take,TakeWhile

     

        為便于下面代碼的演示,,這里先定義一些公共代碼。我們定義一個學(xué)生類Student,,一個學(xué)校類School,,然后定義一個Student的集合類Sudents和一個學(xué)校的集合schools。

 

/// <summary>
    
/// 學(xué)生類
    
/// </summary>
    public class Student
    {
        public int StuId { getset; }
        public string Name { getset; }
        public int Age { getset; }
        public string Class { getset; }
        public int SchoolId { getset; }
    }

    /// <summary>
    
/// 學(xué)校類
    
/// </summary>
    public class School
    {
        public int SchoolId { getset; }
        public string SchoolName { getset; }
    }
  static void Main(string[] args)
        {
             IList<School> schools = new List<School>();
            schools.Add(new School() { SchoolId = 1, SchoolName = "BeiJing Middle School " });
            schools.Add(new School() { SchoolId = 2, SchoolName = "ShangHai Middle School " });
            schools.Add(new School() { SchoolId = 8, SchoolName = "GuangZhou Middle School " });

            IList<Student> students = new List<Student>();
            students.Add(new Student() { StuId = 1, Name = "Li Lei", Age = 9, Class = "Grade Three", SchoolId = 1 });
            students.Add(new Student() { StuId = 2, Name = "Han Meimei", Age = 9, Class = "Grade Three", SchoolId = 1 });
            students.Add(new Student() { StuId = 3, Name = "Li Ming", Age = 6, Class = "Grade One", SchoolId = 2 });
            students.Add(new Student() { StuId = 4, Name = "Zou Qi", Age = 7, Class = "Grade One", SchoolId = 2 });
            students.Add(new Student() { StuId = 5, Name = "Wang Long", Age = 7, Class = "Grade One", SchoolId = 1 });

        }

 

      1,、投影操作符
      1) Select 將序列中的每個元素投影到新表中,。
      代碼演示從students數(shù)據(jù)源中查詢年齡為9歲的學(xué)生,使用Select操作符從返回結(jié)果序列中返回Name和Class兩列,。

     

 var studentSelect = from s in students where s.Age == 9 select new { s.Name, s.Class };
            var studentS = students.Where(s => s.Age == 9);
            foreach (var s in studentSelect)
            {
                Console.WriteLine(s.Name + "\n");
            }

 

      輸出結(jié)果如下:

      Li Lei

      Han Meimei

 

     2) SelectMany 將序列的每個元素投影到 IEnumerable<T> 并將結(jié)果序列合并為一個序列,。
     比如我們需要把students集合中每位學(xué)生的姓名組成一個單詞系列(一個學(xué)生名字可能有多個單詞組成),則可以使用SelectMany操作符,。

    

var studentSelectMany = students.SelectMany(s => s.Name.Split(' '));
            foreach (string s in studentSelectMany)
            {
                Console.WriteLine(s);
            }

 

     輸出結(jié)果如下:

     Li
     Lei
     Han
     Meimei
     Li
     Ming
     Zou
     Qi
     Wang
     Long

 

     2,、限制操作符
     1)Where 對序列中值進(jìn)行過濾,,它不啟動查詢的執(zhí)行,也就是查詢是延遲的,,只有當(dāng)枚舉對象時where才應(yīng)用到數(shù)據(jù)上

     下面示例從學(xué)生集合中過濾名叫LiLei的學(xué)生,,代碼如下:

     

 IEnumerable<Student> studentWhere = students.Where(p => p.Name.Equals("Li Lei"));
            foreach (Student student in studentWhere)
            {
                Console.WriteLine(student.Name);
            }


     輸出結(jié)果如下:

      Li Lei

 

     上面代碼建立查詢語句,但這個語句并沒用立即執(zhí)行,,而是在后面用foreach遍歷stu對象時,,查詢語句才是執(zhí)行,這就是所謂的延遲執(zhí)行,。LINQ的查詢語句執(zhí)行有兩種方式,,一種是延遲執(zhí)行,一種是立即執(zhí)行,。任何返回單個值的LINQ查詢都會立即執(zhí)行,,如我們查詢學(xué)生集合中年齡7歲的學(xué)生個數(shù):var count = (from student in students where student.Age == 7 select student).Count();

 

     3、排序操作符
     1)OrderBy 該操作符對序列元素按照選定的鍵進(jìn)行升序排序
     如對學(xué)生集合中的學(xué)生按照年齡進(jìn)行升序排序:

    

 IEnumerable<Student> studentOrderBy = from student in students orderby student.Age descending select student;
            foreach (Student student in studentOrderBy)
            {
                Console.WriteLine(student.Name + " " + student.Age);
            }

 

     輸出結(jié)果如下:

     Li Lei 9
     Han Meimei 9
     Zou Qi 7
     Wang Long 7
     Li Ming 6

 

     2)OrderByDescending 這個操作符和OrderBy相反,,它是對序列元素按選定的鍵進(jìn)行降序排列

     如對學(xué)生集合中的學(xué)生按照年齡進(jìn)行降序序排序:

    

 IEnumerable<Student> studentOrderByDescending = from student in students orderby student.Age descending select student;
            foreach (Student student in studentOrderByDescending)
            {
                Console.WriteLine(student.Name + " " + student.Age);
            }

 

     輸出結(jié)果如下:

      Li Lei 9
      Han Meimei 9
      Zou Qi 7
      Wang Long 7
      Li Ming 6

 

      3)ThenBy 該操作符實現(xiàn)序列元素按照次關(guān)鍵字進(jìn)行升序排序
      如對學(xué)生集合中先按年齡排序再按姓名排序:

     

IEnumerable<Student> studentThenBy = students.OrderBy(p => p.Age).ThenBy(p => p.Name);
            foreach (Student student in studentThenBy)
            {
                Console.WriteLine(student.Name + "\t" + student.Age);
            }

 

      輸出結(jié)果如下:

      Li Ming 6
      Wang Long       7
      Zou Qi  7
      Han Meimei      9
      Li Lei  9

 

     我們發(fā)現(xiàn)ThenBy操作符并不能在查詢方法中使用只能在方法語法中使用,。熟悉寫SQL語句的讀者可能會問:IEnumerable<Student> sds = students.OrderBy(p => p.Age).ThenBy(p => p.Name);和IEnumerable<Student> sds = students.OrderBy(p => p.Age).OrderBy(p => p.Name);這兩個查詢語句結(jié)果有區(qū)別嗎?區(qū)別是前者是在對主關(guān)鍵字排序結(jié)果上對那些主關(guān)鍵字相同的元素應(yīng)用ThenBy指定的次關(guān)鍵字進(jìn)行排序,,后者是在對第一個OrderBy指定的關(guān)鍵字升序排序的基礎(chǔ)上對所有的元素進(jìn)行第二個OrderBy指定的關(guān)鍵字進(jìn)行升序排序,,毫無疑問,后者第一個OrderBy其實對于結(jié)果是沒有意義的,,因為第二個OrderBy是針對全部元素的,。

 

      4)ThenByDecending 該操作符和ThenBy相反,它按次關(guān)鍵字降序排序

     

IEnumerable<Student> studentThenByDescending = students.OrderBy(p => p.Age).ThenByDescending(p => p.Name);
            foreach (Student student in studentThenByDescending)
            {
                Console.WriteLine(student.Name + "\t" + student.Age);
            }

 

      輸出結(jié)果如下:

      Li Ming 6
      Zou Qi  7
      Wang Long       7
      Li Lei  9
      Han Meimei      9

 

      5)Reverse 該操作符對序列中的元素進(jìn)行反轉(zhuǎn)(逆序)排序
      如把學(xué)生集合類按逆序輸出學(xué)生姓名:

     

IEnumerable<Student> studentThenReverse = students.Reverse();
            foreach (Student student in studentThenReverse)
            {
                Console.WriteLine(student.Name);
            }

 

      輸出結(jié)果如下:

      Wang Long
      Zou Qi
      Li Ming
      Han Meimei
      Li Lei

 

     4,、聯(lián)接操作符
     1)Join 該操作符類似T-SQL中的inner join ,,一個序列通過Join根據(jù)匹配條件聯(lián)接另外一個序列。

      如學(xué)生集合類根據(jù)SchoolId和學(xué)校集合類的SchoolId匹配聯(lián)接,,產(chǎn)生一個新的序列,。

    

 var studentJoin = students.Join(schools, s => s.SchoolId, c => c.SchoolId,
                                   (s, c) => new { StudentName = s.Name, SchoolName = c.SchoolName });
            foreach (var s in studentJoin)
            {
                Console.WriteLine("StudentName:{0}\t SchoolName:{1}", s.StudentName, s.SchoolName);
            }

 

      輸出結(jié)果如下:

      StudentName:Li Lei       SchoolName:BeiJing Middle School
      StudentName:Han Meimei   SchoolName:BeiJing Middle School
      StudentName:Li Ming      SchoolName:ShangHai Middle School
      StudentName:Zou Qi       SchoolName:ShangHai Middle School
      StudentName:Wang Long    SchoolName:BeiJing Middle School

 

      2)GroupJoin 該操作符將主數(shù)據(jù)源的每一個元素和次數(shù)據(jù)源的相應(yīng)的值(根據(jù)某個匹配條件)聯(lián)接起來,返回一個具有層級的結(jié)果集
     
下面代碼演示了打印每一所學(xué)校名稱,,同時打印這所學(xué)校的學(xué)生的名稱,,代碼如下:
  

 var studentGroupJoin = schools.GroupJoin(students, s => s.SchoolId, c => c.SchoolId,
                                   (ss, stus) => new { SchoolName = ss.SchoolName, Students = stus.Select(p => p.Name) });
            foreach (var s in studentGroupJoin)
            {
                Console.WriteLine(s.SchoolName + "\n");
                foreach (var name in s.Students)
                {
                    Console.WriteLine("  " + name);
                }
            }

    

      輸出結(jié)果如下:

      BeiJing Middle School

      Li Lei
      Han Meimei
      Wang Long
      ShangHai Middle School

      Li Ming
      Zou Qi
      GuangZhou Middle School


      5、分組操作符
      1)GroupBy 該操作符根據(jù)一個指定的值將序列中的元素進(jìn)行分組
      下面代碼演示了學(xué)生集合中根據(jù)SchoolId進(jìn)行分組,,代碼如下:

 var studentGroupBy = students.GroupBy(p => p.SchoolId);
            foreach (var st in studentGroupBy)
            {
                Console.WriteLine(st.Key + "\n");
                foreach (var s in st)
                {
                    Console.WriteLine("  " + s.Name);
                }
            }

 

      輸出結(jié)果如下:
      1

          Li Lei
          Han Meimei
          Wang Long
      2

           Li Ming
           Zou Qi


      6,、串聯(lián)操作符
      1)Concat 該操作符將兩個系列合并成一個系列
      下面代碼演示將students的Name和schools中SchoolName合并成一個新的系列,代碼如下:

 

  var studentConcat = students.Select(s => s.Name).Concat(schools.Select(c => c.SchoolName));
            foreach (var st in studentConcat)
            {
                Console.WriteLine(st);

            }


       輸出結(jié)果如下:
        Li Lei
        Han Meimei
        Li Ming
        Zou Qi
        Wang Long
        BeiJing Middle School
        ShangHai Middle School
        GuangZhou Middle School


        7,、聚合操作符
        聚合操作符在一系列的值上執(zhí)行特定的運算,,并返回單個值,如執(zhí)行求和求平均值等。
       1)Aggregate 該操作符將序列中的值進(jìn)行累積并返回結(jié)果

       下面演示使用Aggregate操作符返回學(xué)生集合中所有的學(xué)生名字:
      

 var studentAggregate = students.Select(s => s.Name).Aggregate((n, next) => n + " , " + next);
            Console.WriteLine(studentAggregate);

 

        輸出結(jié)果如下:
        Li Lei , Han Meimei , Li Ming , Zou Qi , Wang Long


        2)Average 該操作符計算一個數(shù)值序列的平均值,。注意它只能應(yīng)用于數(shù)值數(shù)列
        下面代碼演示計算學(xué)生集合中學(xué)生的平均年齡:

        

 var avgAge = students.Select(s => s.Age).Average();
            Console.WriteLine(avgAge);


        輸出結(jié)果如下:

        7.6


        3) Count 該操作符計算一個特定集合中元素的個數(shù),,返回結(jié)果是一個Int32類型的數(shù)值
       如計算學(xué)生集合中學(xué)生的個數(shù):

       

var count = students.Count;
            Console.WriteLine(count);


       輸出結(jié)果如下:

        5


       4)LongCount 該操作符和Count類似也是計算序列中元素的個數(shù),所不同是返回的結(jié)果是一個Int64類型的值
    

 var longCount = students.LongCount();
            Console.WriteLine(longCount);

    

      輸出結(jié)果如下:

       5


       5) Max 該操作符返回一個系列中的最大值,。
       如計算學(xué)生集合中最大的年齡:

      

  var max = students.Max(p => p.Age);
            Console.WriteLine(max);


       輸出結(jié)果如下:

       9


       6) Min 該操作符和Max相反,,返回的是一個序列中的最小值。
    

    var min = students.Min(p => p.Age);
            Console.WriteLine(min);

   

        輸出結(jié)果如下:6


        7)Sum 該操作符計算序列中選定值的總和,。
        計算學(xué)生集合中年齡的總和:
   

 var sum = students.Sum(p => p.Age);
            Console.WriteLine(sum);

    

        輸出結(jié)果如下:

         38


      8,、集合操作符
      集合操作符對元素的集合或序列的集合進(jìn)行操作,并返回一個集合,。
      1) Distinct 該操作符刪除集合中重復(fù)值,,返回的結(jié)果的元素是互不相同的
      如查詢學(xué)生集合中的年齡有多少種。

 var ages = students.Select(p => p.Age).Distinct();
            foreach (int age in ages)
            {
                Console.WriteLine(age);
            }

      

      輸出結(jié)果如下:
       9
       6
       7


      2)Union 該操作符返回兩個系列中每個互不相同的元素,,即兩個集合的并集∪
      我們前面提到Concat操作符,Concat是返回兩個集合的所有元素,,Union則是返回互不相同的元素,。

      如查詢students的StuId和schools的SchoolId的并集,代碼如下:
    

 var studentUnion = students.Select(s => s.StuId).Union(schools.Select(c => c.SchoolId));
            foreach (int id in studentUnion)
            {
                Console.WriteLine(id);
            }

 

      輸出結(jié)果如下:
      1 
      2
      3
      4
      5
      8

 

      3)Intersect 該操作符返回同時存在兩個系列中的元素,,也就是返回兩個系列元素的交集∩
      如查詢students的StuId和schools的SchoolId的交集,,代碼如下:

     

var studentIntersect = students.Select(s => s.StuId).Intersect(schools.Select(c => c.SchoolId));
            foreach (int id in studentIntersect)
            {
                Console.WriteLine(id);
            }


      輸出結(jié)果如下:
      1
      2


     4) Except 該操作符返回的是系列A有,但系列B沒有的元素
     如查詢students有的編號而schools沒有的編號,,代碼如下:

  var studentExcept = students.Select(s => s.StuId).Except(schools.Select(c => c.SchoolId));
            foreach (int id in studentExcept)
            {
                Console.WriteLine(id);
            }

     輸出結(jié)果如下:
     3
     4
     5


     9,、生成操作符
     生成操作符從現(xiàn)有系列的值中創(chuàng)建新的系列。
     1) Empty 該操作符返回一個指定類型的空的 IEnumerable<T>
     下面的代碼示例演示如何使用 Empty<TResult>() 生成一個空 IEnumerable<T>,。
      IEnumerable<decimal> empty = Enumerable.Empty<decimal>();
      下面的代碼示例演示了 Empty<TResult>() 方法的一種可能的用法,。將 Aggregate 方法應(yīng)用于字符串?dāng)?shù)組的集合。僅當(dāng)該數(shù)組包含四個或多個元素時,,集合中的每個數(shù)組的元素被添加到結(jié)果的 IEnumerable<T> 中,。Empty<TResult> 用于生成 Aggregate 的種子值,因為如果集合中沒有包含四個或更多元素的數(shù)組,,則只能返回空序列,。

string[] names1 = { "Hartono, Tommy" };
            string[] names2 = { "Adams, Terry""Andersen, Henriette Thaulow",
                                  "Hedlund, Magnus""Ito, Shu" };
            string[] names3 = { "Solanki, Ajay""Hoeing, Helge",
                                  "Andersen, Henriette Thaulow",
                                  "Potra, Cristina""Iallo, Lucio" };

            List<string[]> namesList =
                new List<string[]> { names1, names2, names3 };

            IEnumerable<string> allNames =
                namesList.Aggregate(Enumerable.Empty<string>(),
                (current, next) => next.Length > 4 ? current.Union(next) : current);

            foreach (string name in allNames)
            {
                Console.WriteLine(name);
            }

     

     輸出結(jié)果如下:
      Solanki, Ajay
      Hoeing, Helge
      Andersen, Henriette Thaulow
      Potra, Cristina
      Iallo, Lucio


      2) Range 該操作符創(chuàng)建一個數(shù)字序列的集合,它包含兩個參數(shù),,第一個是序列的開始值,,第二個參數(shù)是產(chǎn)生序列的個數(shù)
      下面代碼演示創(chuàng)建一個從1到5的數(shù)字序列,然后每個數(shù)字乘以5: 

 var nums = Enumerable.Range(15).Select(n => n * 5);
            foreach (int num in nums)
            {
                Console.WriteLine(num);
            }

    

      輸出結(jié)果如下:
       5
       10
       15
       20
       25

      

       3)Repeat 該操作符創(chuàng)建一個但值序列,,將次值重復(fù)一定的次數(shù),。
       下面代碼演示創(chuàng)建一個包含三個元素的序列,這些元素都是“test”,代碼如下:

 

 var str = Enumerable.Repeat("test"3);
            foreach (string s in str)
            {
                Console.WriteLine(s);
            }


        輸出結(jié)果如下:
        test
        test
        test


       10,、轉(zhuǎn)換操作符
       1)AsEnumerable 該操作符將查詢的輸入以IEnumerable<Of T>類型返回,,也就是可以將實現(xiàn)了IEnumerable<Of T>的數(shù)據(jù)源轉(zhuǎn)換為IEnumerable<Of T>類型本身

       許多類型都實現(xiàn)了IEnumerable。其中一部分還實現(xiàn)了與IEnumerable一模一樣的公共方法,。比如說,,如果你有一個實現(xiàn)了Where方法的類型MyList(跟IEnumerable<T>一樣),那么在MyList上調(diào)用Where將使用MyList的Where實現(xiàn),。如果先調(diào)用AsEnumerable方法然后再調(diào)用Where的話,,你調(diào)用的就是IEnumerable的Where方法而不是MyList的。

 

  class MyList<T> : List<T>
    {

        public IEnumerable<T> Where(Func<T, bool> predicate)
        {
            Console.WriteLine("調(diào)用MyList的Where方法");
            return Enumerable.Where(this, predicate);
        }
    }
pulic void AsE()
{
            MyList<string> names =
                new MyList<string> { "Li Lei""Han Meimei""Li Long"
                    "Wang Ming""Zou Qi""Chen Fei""Wang Tian" };

            //這里調(diào)用MyList的where方法
            IEnumerable<string> query1 =
                names.Where(name => name.Contains("Li"));
            Console.WriteLine(query1.Count());

            //這里隱藏了MyList的where方法,,而是調(diào)用了Enmerable的Where方法,。
            IEnumerable<string> query2 =
                names.AsEnumerable().Where(name => name.Contains("Li"));

            Console.WriteLine(query2.Count());
}


       輸出結(jié)果如下:
      調(diào)用MyList的Where方法
       2
       2


      2)Case 該操作符將IEnumerable集合中的元素轉(zhuǎn)換為某種指定的類型。這樣的好處就是通過提供必要的類型信息,,可以將標(biāo)準(zhǔn)查詢操作符應(yīng)用在非泛型集合上

      如下面代碼演示通過使用Cast操作符,,可以將標(biāo)準(zhǔn)操作符應(yīng)用于查詢ArrayList類型對象的數(shù)據(jù)源(ArrayList沒有實現(xiàn)IEnumerable<Of T>)

 

 ArrayList nameList = new ArrayList();
            nameList.Add("Li Lei");
            nameList.Add("Li Ming");
            nameList.Add("Han Meimei");
            IEnumerable<string> query = nameList.Cast<string>().Where(name => name.Contains("Li"));
            foreach (string s in query)
            {
                Console.WriteLine(s);
            }


      輸出結(jié)果如下:
      Li Lei
      Li Ming


      3) OfType 該操作符可以對一個序列進(jìn)行指定類型的過濾
      下面代碼演示從ArrayList對象中過濾可以轉(zhuǎn)換為Int類型的元素,代碼如下:

 

 ArrayList nameList2 = new ArrayList();
            nameList2.Add(4);
            nameList2.Add("Li Ming");
            nameList2.Add("Han Meimei");
            nameList2.Add(1);
            nameList2.Add(2);
            IEnumerable<int> query3 = nameList2.OfType<int>();
            foreach (int i in query3)
            {
                Console.WriteLine(i);
            }


       輸出結(jié)果如下:
       4
       1
       2


      4)ToArray 該操作符實現(xiàn)從一個IEnumerable序列創(chuàng)建一個數(shù)組,。該操作符會強制查詢立即執(zhí)行
      下面代碼演示將students集合中講學(xué)生名字轉(zhuǎn)換為一個字符串?dāng)?shù)組:

 

 var studentToArray = students.Select(student => student.Name).ToArray();
            Console.WriteLine(studentToArray.Count());

     

     輸出結(jié)果如下:
      5


      5)ToDictionary 該操作符將序列分別轉(zhuǎn)換為一對一的Dictionary<T Key,T Value>字典
      下面代碼演示將students集合中序列轉(zhuǎn)換為以StuId為Key的Dictionary<Int,Student>類型的對象,,代碼如下:

 

  var studentToDictionary = students.ToDictionary(st => st.StuId);
            foreach (KeyValuePair<int, Student> keyValuePair in studentToDictionary)
            {
                Console.WriteLine("Key:{0},Name:{1}", keyValuePair.Key, keyValuePair.Value.Name);
            }

     

      輸出結(jié)果如下:
      Key:1,Name:Li Lei
      Key:2,Name:Han Meimei
      Key:3,Name:Li Ming
      Key:4,Name:Zou Qi
      Key:5,Name:Wang Long


      6) ToList 該操作符將一個IEnumerable序列集合轉(zhuǎn)換為List<Of T>對象,它使得查詢立即執(zhí)行
      下面代碼將students集合中的學(xué)生姓名轉(zhuǎn)換為一個類型為List<string>的字符串集合,,代碼如下:

 

List<string> studenToList = (from student in students select student.Name).ToList();
            foreach (string s in studenToList)
            {
                Console.WriteLine(s);
            }


       輸出結(jié)果如下:
       Li Lei
       Han Meimei
       Li Ming
       Zou Qi
       Wang Long


      7)LookUp 該操作符將序列轉(zhuǎn)換為一對多的LookUp<T Key,TElement Values>字典
      如以班級名稱為主鍵,,Values為該班級的所有學(xué)生,代碼如下:

 

 var lookUp = students.ToLookup(st => st.Class);
            foreach (var grouping in lookUp)
            {
                Console.WriteLine(grouping.Key + "\n");
                foreach (var student in grouping)
                {
                    Console.WriteLine("  " + student.Name);
                }
            }

  
       輸出結(jié)果如下:
       Grade Three

       Li Lei
       Han Meimei
       Grade One

       Li Ming
       Zou Qi
       Wang Long


      11,、元素操作符
      元素操作符從一個系列返回單個特定的元素
      1)DefaultIfEmpty 該操作符將一個空集合替換為包含默認(rèn)的單個值的集合,。在返回序列為空集合時且又需要返回一些對象時,可以通過該操作符返回一個默認(rèn)值
      如果查詢students集合中年齡為5歲的學(xué)生,,因為結(jié)果為空,,可以指定一個默認(rèn)值。代碼如下所示:  

 

 var studentsDefaultIfEmpty = students.Where(s => s.Age == 20).DefaultIfEmpty(new Student() { Name = "默認(rèn)值" });
            foreach (Student student in studentsDefaultIfEmpty)
            {
                Console.WriteLine(student.Name);
            }

      

     輸出結(jié)果如下:
      默認(rèn)值


      2) ElementAt 該操作符返回集合中給定索引處的元素
      如查詢students集合中索引為1的元素,,代碼如下:    

  

 var studentEle = students.ElementAt(1);
            Console.WriteLine(studentEle.Name);

  

      輸出結(jié)果如下:
      Han Meimei


      3)ElementAtOrDefault 該操作符返回指定索引處的元素

      如果該索引超出范圍,,則返回默認(rèn)值,如果是引用類型返回為Null,,如果是值類型則返回為0,。如下面獲取索引為100的學(xué)生,因為索引范圍沒有那么大,,索引返回為null,。         

 

 var studentEleD = students.ElementAtOrDefault(100);
            Console.WriteLine(studentEleD == null ? "返回默認(rèn)值NULL" : studentEleD.Name);


      輸出結(jié)果如下:
      返回默認(rèn)值null


      4)First 該操作符返回序列中的第一個元素
      如果源系列不包含任何元素,F(xiàn)irst方法將拋出一個System.InvalidOperationException
的異常,。
     下面代碼演示返回學(xué)生集合students的第一個元素,。  

 

  var studentFirst = students.First();
            Console.WriteLine(studentFirst.Name);

      
     輸出結(jié)果如下:
     Li Lei


      5)Last 與First操作符相反,該操作符返回序列中的最后一個元素
  

 var studentLast = students.Last();
            Console.WriteLine(studentLast.Name);

  

      輸出結(jié)果如下:
      Wang Long


      6)FirstOrDefault 該 操作符類似First操作符,不同的是,,如果沒有發(fā)現(xiàn)任何元素則返回默認(rèn)值,,元素為引用類型默認(rèn)值為null,值類型為0
     如查詢students集合中學(xué)生年齡為20的學(xué)生的第一個,,代碼如下:

     

 var studentFirstD = students.Where(s => s.Age == 20).FirstOrDefault();
            Console.WriteLine(studentFirstD == null ? "返回默認(rèn)值NULL" : studentFirstD.Name);


     輸出結(jié)果如下:
     返回默認(rèn)值null
      7)LastOrDefault 該操作符類似Last操作符,,不同的是,如果沒有發(fā)現(xiàn)任何元素返回,,則返回默認(rèn)值,,元素為引用類型默認(rèn)值為null,值類型為0
     如查詢students集合中學(xué)生年齡為20的學(xué)生的最后一個,,代碼如下:

     

var studentLastD = students.Where(s => s.Age == 20).FirstOrDefault();
            Console.WriteLine(studentFirstD == null ? "返回默認(rèn)值NULL" : studentLastD.Name);


     輸出結(jié)果如下:
     返回默認(rèn)值null


      8)Single 該操作符返回系列中滿足某一條件的單個元素,,如果滿足條件不止一個元素或零個,則拋出異常
       如獲取students中名字為“Li  Lei”的學(xué)生,,代碼如下:   

 

var studentSingle = students.Single(s => s.Name.Equals("Li Lei"));
            Console.WriteLine(studentSingle.Name);

 
       輸出結(jié)果如下:
       Li Lei


       9)SingleOrDefault 該操作符從一個系列中獲取符合某一條件的唯一元素,,如果沒有符合元素,則返回默認(rèn)值

        元素為引用類型默認(rèn)值為null,,值類型默認(rèn)值為0.注意如果符合條件的元素有多個,,會拋出異常。
       如返回students集合中SchoolId為4的學(xué)生,,代碼如下:

        

 var studentSingleDefault = students.SingleOrDefault(s => s.SchoolId.Equals(4));
            Console.WriteLine(studentSingleDefault == null ? "返回默認(rèn)值null" : studentSingleDefault.Name);


       輸出結(jié)果如下:
       返回默認(rèn)值null


       12、相等操作符
       1)SequenceEqual操作符可以判定兩個集合是否相等,返回值為Boolean值
   

  var studentS1 = students.Where(s => s.SchoolId == 1);
            var studentS2 = students.Where(s => s.SchoolId == 1);
            Console.WriteLine(studentS1.SequenceEqual(studentS2));

    

        輸出結(jié)果如下:
        True


        13.量詞操作符
        1)All 該操作符判斷系列的所有元素是否都滿足某一條件,,返回值為Boolean值
        如判斷students集合中是否所有學(xué)生名字都以“L”開頭,,代碼如下:

 bool blAll = students.All(s => s.Name.StartsWith("L"));
            Console.WriteLine(blAll);

        輸出結(jié)果如下:
        False


        2)Any 該操作符判斷集合是否至少一個元素滿足某一條件,返回值為Boolean值
 

  bool blAny = students.Any(s => s.Name.StartsWith("L"));
            Console.WriteLine(blAny);

      

        輸出結(jié)果如下:
        True


        3)Contains 該操作符判斷系列是否包含某個特定的元素,,返回值為Boolean
        如判斷名稱集合中是否包含“Li Lei”這個名稱,,代碼如下:

 string studentName = "Li Lei";
            bool blContains = students.Select(s => s.Name).Contains(studentName);
            Console.WriteLine(blContains);

        輸出結(jié)果如下:
        True


       14、分割操作符
       1)Skip 該操作符能夠掉到一定的元素到達(dá)一個指定位置,,并且從該位置開始返回其余的元素
       如跳過students集合的前兩個元素,,讀取剩下的元素,代碼如下:

 

 var studentSkip = students.Skip(2);
            foreach (Student student in studentSkip)
            {
                Console.WriteLine(student.Name);
            }

       

      輸出結(jié)果如下:
       Li Ming
       Zou Qi
      Wang Long


      2)SkipWhile 該操作符基于特定的謂詞略過某些符合條件的元素,,返回其余的元素

      這里需要特別注意,,SkipWhile對數(shù)據(jù)源進(jìn)行枚舉,從第一個枚舉得到的元素開始,,如果返回true,,則跳過該元素,繼續(xù)進(jìn)行枚舉操作。但是,如果一旦返回false,,則該元素以后的所有元素,都不會再調(diào)用SkipWhile,。

 

 int[] numSkipWhile = new int[] { 579694 };
            var numSw = numSkipWhile.SkipWhile(n => n < 9);
            foreach (int i in numSw)
            {
                Console.WriteLine(i);
            }

     

      輸出結(jié)果為:
       9
       6
       9
       4   


      如果數(shù)組numSkipWhile為{9,5,7,9,6,9,4},則輸出結(jié)果為:
      9
      5
      7
      9
      6
      9
      4


      3)Take 該操作符返回某個系列中連續(xù)的元素子序列,子序列開始于序列的開頭,,結(jié)尾為某個指定的參數(shù),,如果指定的參數(shù)超過索引,則返回到系列的結(jié)尾為止

 

 int[] numTake = new int[] { 579694 };
            var numTk = numTake.Take(3);
            foreach (int i in numTk)
            {
                Console.WriteLine(i);
            }

     輸出結(jié)果為 :
     5
     7
     9


     4) TakeWhile 該操作符通過特定的條件選取元素,如果某個元素不符合條件,則從該元素起的元素全部跳過

int[] numTaleWhile = new int[] { 579694 };
            var numTw = numTaleWhile.TakeWhile(n => n < 9);
            foreach (int i in numTw)
            {
                Console.WriteLine(i);
            }

    

    輸出結(jié)果為:
     5
     7

 

 

 


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多