溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#如何使用LINQ查詢操作符

發(fā)布時(shí)間:2022-06-15 09:08:41 來源:億速云 閱讀:139 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“C#如何使用LINQ查詢操作符”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C#如何使用LINQ查詢操作符”吧!

連表操作符

1、內(nèi)連接

1、使用 join 子句 根據(jù)特定的條件合并兩個(gè)數(shù)據(jù)源,但之前要獲得兩個(gè)要連接的列表。

業(yè)務(wù)說明:返回1958到1965年間的車手冠軍和車隊(duì)冠軍信息,根據(jù)年份關(guān)聯(lián)

var racers = from r in Formula1.GetChampions()
             from y in r.Years
             select new
             {
                 Year = y,
                 Name = r.FirstName + " " + r.LastName
             };

var teams = from t in Formula1.GetContructorChampions()
            from y in t.Years
            select new
            {
                Year = y,
                Name = t.Name
            };

var racersAndTeams0 =
      (from r in racers
       join t in teams on r.Year equals t.Year
       orderby t.Year
       select new
       {
           Year = r.Year,
           Racer = r.Name,
           Team = t.Name
       }).Take(10);

方法語法:

var racersAndTeams = racers
    .Join(teams, r => r.Year, t => t.Year, (r, t) => new { Year = r.Year, Racer = r.Name, Team = t.Name })
    .OrderBy(p => p.Year).Take(10);

結(jié)果:

Year  Champion             Constructor Title 
1958: Mike Hawthorn        Vanwall 
1959: Jack Brabham         Cooper 
1960: Jack Brabham         Cooper 
1961: Phil Hill            Ferrari 
1962: Graham Hill          BRM 
1963: Jim Clark            Lotus 
1964: John Surtees         Ferrari 
1965: Jim Clark            Lotus 
1966: Jack Brabham         Brabham 
1967: Denny Hulme          Brabham

2、或者合并成一個(gè)LINQ 查詢

var racersAndTeams =
          (from r in
               from r1 in Formula1.GetChampions()
               from yr in r1.Years
               select new
               {
                   Year = yr,
                   Name = r1.FirstName + " " + r1.LastName
               }
           join t in
               from t1 in Formula1.GetContructorChampions()
               from yt in t1.Years
               select new
               {
                  Year = yt,
                  Name = t1.Name
               }
           on r.Year equals t.Year
           orderby t.Year
           select new
           {
               Year = r.Year,
               Racer = r.Name,
               Team = t.Name
           }).Take(10);

方法語法

var racersAndTeams0 = Formula1.GetChampions()
               .SelectMany(m => m.Years, (m, y) => new { Racer = m, Year = y })
               .Join(Formula1.GetContructorChampions()
               .SelectMany(m => m.Years, (m, y) => new { Team = m, Year = y })
               , m => m.Year, m1 => m1.Year
               , (m, m1) => new
               {
                   Year = m.Year,
                   Racer = m.Racer.FirstName + " " + m.Racer.LastName,
                   Team = m1.Team.Name
               })
               .OrderBy(m => m.Year).Take(10);

2、左外連接(DefaultIfEmpty)

左外連接返回左邊序列中的全部元素,即使它們在右邊的序列中并沒有匹配的元素。

左外連接用join子句和 DefaultIfEmpty 方法定義。 使用 DefaultIfEmpty 定義其右側(cè)的默認(rèn)值。

linq只支持左連接,如要右連接,將query和query1調(diào)換位置

業(yè)務(wù)說明:如賽車手比車隊(duì)設(shè)立冠軍的年份要早,可能某個(gè)年份只有賽車手冠軍沒有車隊(duì)冠軍,這時(shí)候需要左連接查詢。

var racers = from r in Formula1.GetChampions()
             from y in r.Years
             select new
             {
                 Year = y,
                 Name = r.FirstName + " " + r.LastName
             };

var teams = from t in Formula1.GetContructorChampions()
            from y in t.Years
            select new
            {
                Year = y,
                Name = t.Name
            };


var racersAndTeams =
  (from r in racers
   join t in teams on r.Year equals t.Year into rt
from t in rt.DefaultIfEmpty()
   orderby r.Year
   select new
   {
       Year = r.Year,
       Champion = r.Name,
       Constructor = t == null ? "no constructor championship" : t.Name
   }).Take(10);

foreach (var item in racersAndTeams)
{
    Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Champion, item.Constructor);
}

結(jié)果

1950: Nino Farina          no constructor championship 
1951: Juan Manuel Fangio   no constructor championship 
1952: Alberto Ascari       no constructor championship 
1953: Alberto Ascari       no constructor championship 
1954: Juan Manuel Fangio   no constructor championship 
1955: Juan Manuel Fangio   no constructor championship 
1956: Juan Manuel Fangio   no constructor championship 
1957: Juan Manuel Fangio   no constructor championship 
1958: Mike Hawthorn        Vanwall 
1959: Jack Brabham         Cooper

3、組連接

左外連接使用了組連接和 into 子句。它有一部分與組連接相同,只不過組連接不適用 DefaultIfEmpty 方法。

使用組連接時(shí),基于鍵相等對兩個(gè)兩個(gè)獨(dú)立的序列的元素進(jìn)行關(guān)聯(lián)并對結(jié)果進(jìn)行分組。

常應(yīng)用于返回“主鍵對象-外鍵對象集合”形式的查詢。

業(yè)務(wù)說明:返回1958到1965年間的車手冠軍和車隊(duì)冠軍信息,根據(jù)年份關(guān)聯(lián)并分組

注意:直接出現(xiàn)在join子句之后的into關(guān)鍵字會被翻譯為GroupJoin,而在select或group子句之后的into表示繼續(xù)一個(gè)查詢。

// 查詢表達(dá)式
var racersAndTeams =( from r in racers
                     join t in teams on r.Year equals t.Year into groupTeams
                     select new
                     {
                         Year = r.Year,
                         Racer = r.Name,
                         GroupTeams = groupTeams
                     }).Take(10);

方法語法:

var racersAndTeams1 = racers
    .GroupJoin(teams, r => r.Year, t => t.Year, (r, t) => new { Year = r.Year, Racer = r.Name, GroupTeams = t }
    ).Take(10);;

foreach (var item in racersAndTeams)
{
    Console.WriteLine("{0}: {1,-20} {2}", item.Year, item.Racer, item.GroupTeams.Count());
}

結(jié)果:

1950: Nino Farina          0 
1952: Alberto Ascari       0 
1953: Alberto Ascari       0 
1951: Juan Manuel Fangio   0 
1954: Juan Manuel Fangio   0 
1955: Juan Manuel Fangio   0 
1956: Juan Manuel Fangio   0 
1957: Juan Manuel Fangio   0 
1958: Mike Hawthorn        1 
1961: Phil Hill            1

2、join…on…equals…支持多個(gè)鍵關(guān)聯(lián),可以使用匿名類型來對多個(gè)鍵值進(jìn)行Join,如下所示:

// 查詢表達(dá)式
var query17 = from r in racers
              join r2 in teams on new { Name = r.Name.Substring(0, 1), Year = r.Year } equals new { Name = r2.Name.Substring(0, 1), Year = r2.Year } into yearResults
              select new
              {
                  Results = yearResults
              };

foreach (var item in query17)
{
    foreach (var info in item.Results)
    {
        Console.WriteLine(info.Name);
    }
}
//McLaren

集合操作

集合操作通過調(diào)用實(shí)體類的 GetHashCode() 和 Equals() 方法比較對象。 對于自定義比較,可以傳遞實(shí)現(xiàn) IEqualityComparer接口的對象。

業(yè)務(wù)說明:獲取使用車型”Ferrari”和車型”Mclaren”都獲得過車手冠軍車手列表

void Main()
{
    Func<string, IEnumerable<Racer>> racersByCar = car => from r in Formula1.GetChampions()
                                                          from c in r.Cars
                                                          where c == car
                                                          orderby r.LastName
                                                          select r;

    foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren"), new RacerComparer()))
    {
        Console.WriteLine(racer);
    }
}


public class RacerComparer : IEqualityComparer<Racer>
{
    public bool Equals(Racer x, Racer y)
    {
        if (Object.ReferenceEquals(x, y)) return true;
        return x != null && y != null && x.FirstName == y.FirstName && x.LastName == y.LastName;
    }

    public int GetHashCode(Racer obj)
    {
        int hashStudentId = obj.FirstName.GetHashCode();
        int hashScore = obj.LastName.GetHashCode();
        return hashStudentId ^ hashScore;
    }
}

結(jié)果:

Niki Lauda

  • 1) Union:并集,返回兩個(gè)序列的并集,去掉重復(fù)元素。

  • 2) Concat:連接,返回兩個(gè)序列的并集。

  • 3) Intersect:交集,返回兩個(gè)序列中都有的元素,即交集。

  • 4) Except:差集,返回只出現(xiàn)在一個(gè)序列中的元素,即差集。

示例:合并html開始標(biāo)簽和結(jié)束標(biāo)簽

var letters = new string[] { "A", "B", "C", "D", "E" };
var numbers = new int[] { 1, 2, 3 };
var q = letters.Zip(numbers, (l, n) => l + n.ToString());
foreach (var s in q)
    Console.WriteLine(s);

結(jié)果:

A1 
B2 
C3

  • 5) Zip:通過使用指定的委托函數(shù)合并兩個(gè)序列,集合的總個(gè)數(shù)不變。

示例:

int[] arr1 = { 1, 4, 7, 9 };
int[] arr2 = { 1, 7, 9, 4 };
Console.WriteLine("排序前 是否相等:{0}"
    , arr1.SequenceEqual(arr2) ? "是" : "否");  // 否
Console.WriteLine();
Console.WriteLine("排序后 是否相等:{0}"
    , arr1.SequenceEqual(arr2.OrderBy(k => k)) ? "是" : "否"); // 是
  • 6) SequenceEqual:判斷兩個(gè)序列是否相等,需要內(nèi)容及順序都相等。

分區(qū)操作符

擴(kuò)展方法 Take() 和 Skip() 等的分區(qū)操作可以用于分頁。

添加在查詢的“最后”,返回集合的一個(gè)子集。

1、Take()

從序列的開頭返回指定數(shù)量的連續(xù)元素。

2、TakeWhile()

只要滿足指定的條件,就會返回序列的元素。

從第一個(gè)元素開始, 讀取Starts小于40的人員列表,只要遇到大于40的元素就立即停止返回。

var racers = (from r in Formula1.GetChampions()
              orderby r.Starts
              select r
              )
              <strong>.TakeWhile(p </strong><strong>=&gt; p.Starts &lt; 40</strong><strong>);</strong>

foreach (var name in racers)
{
    Console.WriteLine($"{name:A}");
}

    結(jié)果:

    Alberto Ascari, Italy; starts: 32, wins: 10 
    Nino Farina, Italy; starts: 33, wins: 5

    3、Skip()

    跳過序列中指定數(shù)量的元素,然后返回剩余的元素。

    業(yè)務(wù)說明:將車手冠軍列表按每頁5個(gè)名字進(jìn)行分頁。

    int pageSize = 5;
    
    int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() / (double)pageSize);
    
    for (int page = 0; page &lt; numberPages; page++)
    {
        Console.WriteLine("Page {0}", page);
    
        var racers = (
                      from r in Formula1.GetChampions()
                      orderby r.LastName
                      select r.FirstName + " " + r.LastName
                      )
                      .Skip(page * pageSize).Take(pageSize);
    
        foreach (var name in racers)
        {
            Console.WriteLine(name);
        }
    }

    結(jié)果:

    Page 0 
    Fernando Alonso 
    Mario Andretti 
    Alberto Ascari 
    Jack Brabham 
    Jim Clark 
    Page 1 
    Juan Manuel Fangio 
    Nino Farina 
    Emerson Fittipaldi 
    Mika Hakkinen 
    Mike Hawthorn

      4、SkipWhile():

      只要滿足指定的條件,就跳過序列中的元素,然后返回剩余元素。

      聚合操作符

      聚合操作符返回一個(gè)值。

      1、Count: 返回集合項(xiàng)數(shù)。     

      2、LongCount:返回一個(gè) System.Int64,表示序列中的元素的總數(shù)量。

      業(yè)務(wù)說明:下面的Count 方法只返回獲得冠軍次數(shù)超過三次的賽車手,因?yàn)橥粋€(gè)查詢中需要使用同一個(gè)計(jì)數(shù)超過一次,所以使用let 子句定義了一個(gè)變量 numberYear.

      var query = from r in Formula1.GetChampions()
                  let numberYears = r.Years.Count()
                  where numberYears &gt;= 3
                  orderby numberYears descending, r.LastName
                  select new
                  {
                      Name = r.FirstName + " " + r.LastName,
                      TimesChampion = numberYears
                  };
      
      foreach (var r in query)
      {
          Console.WriteLine("{0} {1}", r.Name, r.TimesChampion);
      }
      //Michael Schumacher 7
      //Juan Manuel Fangio 5
      //Alain Prost 4
      //Jack Brabham 3
      //Niki Lauda 3
      //Nelson Piquet 3
      //Ayrton Senna 3
      //Jackie Stewart 3

      3、Sum: 序列中的所有數(shù)字的和。

      業(yè)務(wù)說明:下面的Sum 方法用于計(jì)算一個(gè)國家贏得比賽的總次數(shù)。

      首先根據(jù)國家對賽車手分組,再在新創(chuàng)建的匿名類型中,把Wins 屬性賦予某個(gè)國家贏得比賽的總次數(shù)。

      var countries = (from c in
                           from r in Formula1.GetChampions()
                           group r by r.Country into c
                           select new
                           {
                               Country = c.Key,
                               Wins = (from r1 in c
                                       select r1.Wins).Sum()
                           }
                       orderby c.Wins descending, c.Country
                       select c).Take(5);
      
      foreach (var country in countries)
      {
          Console.WriteLine("{0} {1}", country.Country, country.Wins);
      }
      //UK 138
      //Germany 91
      //Brazil 78
      //France 51
      //Finland 40

      4、Min: 返回集合中的最小值。

      5、Max: 返回集合中的最大值。

      6、Average: 返回集合中的平均值。

      7、Aggregate: 傳遞一個(gè) lambda 表達(dá)式,該表達(dá)式對所有的值進(jìn)行聚合。

      業(yè)務(wù)說明:Aggregate的 
      第一個(gè)參數(shù)是算法的種子,即初始值。(可選) 
      第二個(gè)參數(shù)是一個(gè)表達(dá)式,用來對每個(gè)元素進(jìn)行計(jì)算(委托第一個(gè)參數(shù)是累加變量,第二個(gè)參數(shù)當(dāng)前項(xiàng))。 
      第三個(gè)參數(shù)是一個(gè)表達(dá)式,用來對最終結(jié)果進(jìn)行數(shù)據(jù)轉(zhuǎn)換

      int[] numbers = { 1, 2, 3 };
      int y = numbers.Aggregate((tol, n) =&gt; prod + n); // 1+2+3 = 6
      int x = numbers.Aggregate(0, (tol, n) =&gt; tol + n); // 0+1+2+3 = 6
      int z = numbers.Aggregate(0, (tol, n) =&gt; tol + n, r =&gt; r * 2);// (0+1+2+3)*2 = 12

      轉(zhuǎn)換操作符

      查詢可以推遲到訪問數(shù)據(jù)項(xiàng)時(shí)再執(zhí)行。在迭代中使用查詢時(shí),查詢會執(zhí)行。

      而使用轉(zhuǎn)換操作符會立即執(zhí)行查詢,把查詢結(jié)果放在數(shù)組、列表或字典中。

      LINQ本身支持四種不同的集合生成方式,包含生成數(shù)組的ToArray()、生成列表的ToList、生成字典集合的ToDictionary 以及生成Lookup<tkey,telement>類的ToLookup。

      1) Cast:

      將非泛型的 IEnumerable 集合元素轉(zhuǎn)換為指定的泛型類型,若類型轉(zhuǎn)換失敗則拋出異常。 
      如果需要在非類型化的集合上(如ArrayList)使用LINQ 查詢,就可以使用Cast 方法。

      在下面的例子中,基于Object類型的ArrayList集合用Racer對象填充。

      var list = new ArrayList(Formula1.GetChampions() as System.Collections.ICollection);
      
      var query = from r in list.Cast()
                  where r.Country == "USA"
                  orderby r.Wins descending
                  select r;
      foreach (var racer in query)
      {
          Console.WriteLine("{0:A}", racer);
      }
      //Mario Andretti, USA; starts: 128, wins: 12
      //Phil Hill, USA; starts: 48, wins: 3

      2) ToArray:

      從 IEnumerable 創(chuàng)建一個(gè)數(shù)組。

      3) ToList:

      立即執(zhí)行查詢,從 IEnumerable 創(chuàng)建一個(gè) List。

      4) ToDictionary:

      根據(jù)指定的鍵選擇器函數(shù),從 IEnumerable 創(chuàng)建一個(gè) Dictionary<tkey,tvalue>。

      將列表轉(zhuǎn)換為字典:

      var spartans = new List&lt;dynamic&gt;
              {
                  new {Opponent="UAB",Score="55-18"},
                  new {Opponent="Bowling Green",Score="55-18"},
                  new {Opponent="Pittsburgh",Score="55-18"},
                  new {Opponent="Notre Dame",Score="55-18"}
              };
      //字典是一種鍵值對的集合,ToDictionary 將一個(gè)IEnumerable&lt;T&gt;對象(比如LINQ查詢所返回的結(jié)果)
      //轉(zhuǎn)換為一個(gè)IDictionary&lt;Key,Value&gt;對象。
      IDictionary&lt;string, dynamic&gt; stats = spartans.ToDictionary(key =&gt; (string)key.Opponent);
      Console.WriteLine("Spartans vs. {0} {1}", stats["Notre Dame"].Opponent, stats["Notre Dame"].Score);

      5) ToLookup:

      根據(jù)指定的鍵選擇器函數(shù),從 IEnumerable 創(chuàng)建一個(gè) System.Linq.Lookup。 
      ToLookup使用比較復(fù)雜,Lookup類似于Dictionary,不過,Dictionary每個(gè)鍵只對應(yīng)一個(gè)值,而Lookup則是1:n 的映射。 
      Lookup沒有公共構(gòu)造函數(shù),而且是不可變的。在創(chuàng)建Lookup之后,不能添加或刪除其中的元素或鍵。(可以將ToLookup 視為GroupBy與ToDictionary的功能合體) 
      業(yè)務(wù)說明:將車手冠軍按其使用車型進(jìn)行分組,并顯示使用”williams”車型的車手名字。

      ILookup&lt;string, Racer&gt; racers =
          (from r in Formula1.GetChampions()
           from c in r.Cars //使用復(fù)合的from 查詢
           select new
           {
               Car = c,
               Racer = r
           }
           ).ToLookup(cr =&gt; cr.Car, cr =&gt; cr.Racer);
      
      if (racers.Contains("Williams"))
      {
          foreach (var williamsRacer in racers["Williams"])
          {
              Console.WriteLine(williamsRacer);
          }
      }
      //Alan Jones
      //Keke Rosberg
      //Nelson Piquet
      //Nigel Mansell
      //Alain Prost
      //Damon Hill
      //Jacques Villeneuve

      6) DefaultIfEmpty:

      返回指定序列的元素;如果序列為空,則返回包含類型參數(shù)的默認(rèn)值的單一元素集合 。   

      var defaultArrCount = (new int[0]).DefaultIfEmpty().Count();
      Console.WriteLine(defaultArrCount);
      //1

      7) AsEnumerable:

      返回類型為 IEnumerable 。用于處理LINQ to Entities操作遠(yuǎn)程數(shù)據(jù)源與本地集合的協(xié)作

      生成操作符

      生成操作符返回一個(gè)新的集合。三個(gè)生成操作符不是擴(kuò)展方法,而是返回序列的正常靜態(tài)方法。

      1) Empty:

      生成一個(gè)具有指定類型參數(shù)的空序列 IEnumerable。 
      Empty() 方法返回一個(gè)不返回值的迭代器,用于需要一個(gè)集合的參數(shù),可以給參數(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&lt;string[]&gt; namesList = new List&lt;string[]&gt; { names1, names2, names3 };
      
      IEnumerable&lt;string&gt; allNames =  namesList.Aggregate(Enumerable.Empty&lt;string&gt;(), (current, next) =&gt; next.Length &gt; 3 ? current.Union(next) : current);
      
      foreach (string name in allNames)
      {
          Console.WriteLine(name);
      }
      //Adams, Terry
      //Andersen, Henriette Thaulow
      //Hedlund, Magnus
      //Ito, Shu
      //Solanki, Ajay
      //Hoeing, Helge
      //Potra, Cristina
      //Iallo, Lucio

      2) Range:

      生成指定范圍內(nèi)的整數(shù)的序列 IEnumerable。 
      如需要填充一二范圍的數(shù)字,此時(shí)就應(yīng)使用 Range() 方法。這個(gè)方法第一個(gè)參數(shù)作為起始值,把第二個(gè)參數(shù)作為要填充的項(xiàng)數(shù)。

      var values = Enumerable.Range(1, 20);
      
      foreach (var value in values)
      {
          Console.WriteLine(value);
      }
      // 結(jié)果 1 2 3 4 5 6 ......  19 20

      Range() 方法不返回填充所定義值的集合,與其他方法一樣,推遲查詢,返回一個(gè) RangeEnumerator。其中用 yield return 語句,來遞增值。該結(jié)果也可以與其他擴(kuò)展方法一起用。

      var values = Enumerable.Range(1, 5).Select(n =&gt; n * 3);
      
      foreach (var value in values)
      {
           Console.WriteLine(value);
      }
      // 3 6 9 12 15

      3) Repeat:

      生成包含一個(gè)重復(fù)值的序列 IEnumerable。 
      Repeat() 方法 返回一個(gè)迭代器,把同一個(gè)值重復(fù)特定的次數(shù)。

      IEnumerable&lt;string&gt; strings = Enumerable.Repeat("I like programming.", 3);
      
      foreach (String str in strings)
      {
          Console.WriteLine(str);
      }
      //I like programming.
      //I like programming.
      //I like programming.

      量詞操作符

      如果元素序列滿足指定的條件,量詞操作符就返回布爾值。

      1) Any:

      確定序列是否包含任何元素;或確定序列中的任何元素是否都滿足條件。

      //獲取是否存在姓為“Schumacher”的車手冠軍
      var hasRacer_Schumacher = Formula1.GetChampions().Any(r =&gt; r.LastName == "Schumacher");
      Console.WriteLine(hasRacer_Schumacher);
      //True

      2) All:

      確定序列中的所有元素是否滿足條件。

      3) Contains:

      確定序列是否包含指定的元素。

      元素操作符

      這些元素操作符僅返回一個(gè)元素,不是IEnumerable。(默認(rèn)值:值類型默認(rèn)為0,引用類型默認(rèn)為null)

      業(yè)務(wù)說明:獲取冠軍數(shù)排名第三的車手冠軍

      var Racer3 = Formula1.GetChampions()
          .OrderByDescending(r =&gt; r.Wins)
          .ElementAtOrDefault(2);
      
      Console.WriteLine(Racer3);
      //Ayrton Senna
      • 1) First:返回序列中的第一個(gè)元素;如果是空序列,此方法將引發(fā)異常。

      • 2) FirstOrDefault:返回序列中的第一個(gè)元素;如果是空序列,則返回默認(rèn)值default(TSource)。

      • 3) Last:返回序列的最后一個(gè)元素;如果是空序列,此方法將引發(fā)異常。

      • 4) LastOrDefault:返回序列中的最后一個(gè)元素;如果是空序列,則返回默認(rèn)值default(TSource)。

      • 5) Single:返回序列的唯一元素;如果是空序列或序列包含多個(gè)元素,此方法將引發(fā)異常。

      • 6) SingleOrDefault:返回序列中的唯一元素;如果是空序列,則返回默認(rèn)值default(TSource);如果該序列包含多個(gè)元素,此方法將引發(fā)異常。

      • 7) ElementAt:返回序列中指定索引處的元素,索引從0開始;如果索引超出范圍,此方法將引發(fā)異常。

      • 8) ElementAtOrDefault:返回序列中指定索引處的元素,索引從0開始;如果索引超出范圍,則返回默認(rèn)值default(TSource)。

      并行查詢,并行Linq

      AsParallel() 方法,擴(kuò)展 IEnumerable 接口,返回 ParallelQuery類,所以正常的集合類可以以平行方式查詢。

      var query24 = from r in Formual.GetChampions().AsParallel() select r;

      分區(qū)器

      AsParallel()方法不僅擴(kuò)展了 IEnumerable 接口,還擴(kuò)展了 Partitioner 類。通過它,可以影響創(chuàng)建的分區(qū)。

      手動創(chuàng)建一個(gè)分區(qū)器

      var query25 = from r in Partitioner.Create (Formual.GetChampions(), true).AsParallel() select r;

      取消

      .NET 提供一個(gè)標(biāo)準(zhǔn)方法,來取消長時(shí)間運(yùn)行的任務(wù),也適用于并行Linq。

      要取消長時(shí)間運(yùn)行的查詢可以給查詢添加WithCancellation() 方法,并傳遞一個(gè) CancellactionToken令牌作為參數(shù)。

      CancelllationToken令牌從CancellactionTokenSource類中創(chuàng)建。該查詢在單獨(dú)的線程中運(yùn)行,在該線程中,捕獲一個(gè)OperationCanceledException類型的異常。如果取消了查詢就觸發(fā)這個(gè)異常。

      在主線程中,調(diào)用CancellationTokenSource類的Cancel()方法可以取消任務(wù)。

      CancellationTokenSource cts = new CancellationTokenSource();
      
      Task.Factory.StartNew(() =&gt;
      {
          try
          {
              var res = from r in Formual.GetChampions().AsParallel().WithCancellation(cts.Token) select r;
              Console.WriteLine("query finished, sum:{0}", res);
          }
          catch (OperationCanceledException ex)
          {
              Console.WriteLine("canceled!");
              Console.WriteLine(ex.Message);
          }
      });
      
      string input = Console.ReadLine();
      if (input.ToLower().Equals("y"))
      {
          cts.Cancel();
          Console.WriteLine("canceled 2!");
      }

      感謝各位的閱讀,以上就是“C#如何使用LINQ查詢操作符”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C#如何使用LINQ查詢操作符這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

      向AI問一下細(xì)節(jié)

      免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

      AI