《C#高级编程》学习总结之LINQ

时间:2023-03-08 16:01:37
《C#高级编程》学习总结之LINQ

一、标准的查询操作符

标准查询操作符 说明

Where

OfType<TResult>

筛选操作符定义了返回元素的条件。

Select

SelectMany

投射操作符用于把对象转换为另一个类型的新对象。

OrderBy

ThenBy

OrderByDescending

ThenByDescending

Reverse

排序操作符改变所返回的元素的顺序。OrderBy升序,OrderByDescending降序。如果第一次排序的结果很类型,可以使用ThenBy和ThenBy Descending操作符进行第二次排序,Reverse翻转集合中元素的顺序。

Join

GroupJoin

连接操作符用于合并不直接相关的集合。Join操作符根据键选择器关联两个集合。GroupJoin操作符连接两个集合,组合其结果。

GroupBy

ToLookup

组合操作符把数据分组。GroupBy操作符组合有公共键的元素。ToLookup通过创建一个一对多字典,来组合元素。

Any

All

Contains

如果元素序列满足指定的条件,限定符操作符就返回布尔值。Any确定集合中是否有满足谓词函数的元素;All确定集合中的所有元素是否都满足谓词函数;Contains检查某个元素是否存在集合中。

Take

Skip

TakeWhile

SkipWhile

分区操作符返回集合的一个子集。使用Take必须指定要从集合中提取的元素个数;Skip跳过指定的元素个数;TakeWhile提取条件为真的元素;SkipWhile跳过条件为真的元素。

Distinct

Union

Intersect

Except

Zip

Set操作符返回一个集合。Distinct从集合中删除重复的元素;Union返回出现在其中一个集合中的唯一元素;Intersect返回两个集合中都有的元素;Except返回只出现在一个集合中的元素;Zip把两个集合合并成一个。

First

FirstOrDefault

Last

LastOrDefault

ElementAt

ElementAtOrDefault

Single

SingleOrDefault

元素操作符仅返回一个元素。First返回第一个满足条件的元素;FirstOrDefault类似于First,但如果没找到满足条件的元素就返回默认值;Last返回最后一个满足条件的元素;ElementAt制定了要返回的元素的位置。Single只返回一个满足条件的元素,如果有多个元素满足条件,则抛出一个异常。

Count

Sum

Min

Max

Average

Aggregate

聚合操作符计算集合的一个值。

ToArray

AsEnumerable

ToList

ToDictionary

Cast<TResult>

这些转换操作符将集合转换为数组。

Empty

Range

Repeat

生成操作符返回一个新集合。使用Empty时集合是空的;Range返回一系列数字;Repeat返回一个始终重复一个值的集合。
  • 筛选操作符Where
 , , , , , , , ,  };

            var query = from r in arr

                        select r;
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
  • 使用索引筛选
 //找出数组中大于5且索引不为偶数的元素
            , , , , , , , ,  };

             && index %  != );
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
  • 类型筛选
 //筛选集合中为string类型的元素
            , ,  };
            var query = obj.OfType<string>();
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
  • 复合的from子句

如果需要根据对象的一个成员进行筛选,而该成员本身又是一个集合,就可以使用符合的from子句。

var ferrariDrivers = from r in Formula1.GetChampions()
                                 from c in r.Cars
                                 where c == "Ferrari"
                                 orderby r.LastName
                                 select r.FirstName + " " + r.LastName;
            foreach (var item in ferrariDrivers)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
  • 排序
 , , , , , , , ,  };
            var query = (from r in myInt
                        orderby r descending
                        );
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
  • 分组
var countries = from r in Formula1.GetChampions()
                            group r by r.Country into g
                            orderby g.Count() descending, g.Key

                            select new
                            {
                                COUNTRY = g.Key,
                                COUNT = g.Count()
                            };
            foreach (var item in countries)
            {
                Console.WriteLine("{0} {1}", item.COUNTRY, item.COUNT);
            }
            Console.ReadLine();
  • 对嵌套对象分组
 var countries = from r in Formula1.GetChampions()
                            group r by r.Country into g
                            orderby g.Count() descending, g.Key

                            select new
                            {
                                Country = g.Key,
                                Count = g.Count(),
                                Racers = from r1 in g
                                         orderby r1.LastName
                                         select r1.FirstName + " " + r1.LastName
                            };
            foreach (var item in countries)
            {
                Console.WriteLine("{0} {1}", item.Country, item.Count);
                foreach (var name in item.Racers)
                {
                    Console.Write("{0};", name);
                }
                Console.WriteLine();
            }
            Console.ReadLine();
  • 内连接
 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
                                  select new
                                  {
                                      r.Year,
                                      Champion = r.Name,
                                      Constructor = t.Name
                                  }).Take();
            Console.WriteLine("Year World Champio\t Constructor Title");
            foreach (var item in racersAndTeams)
            {
                Console.WriteLine("{0}:{1,-20} {2}", item.Year, item.Champion, item.Constructor);
            }
            Console.ReadLine();
  • 左外连接
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
                                  {
                                      r.Year,
                                      Champion = r.Name,
                                      Constructor = t == null ? "no constructor championship" : t.Name
                                  }).Take();
            Console.WriteLine("Year World Champio\t Constructor Title");
            foreach (var item in racersAndTeams)
            {
                Console.WriteLine("{0}:{1,-20} {2}", item.Year, item.Champion, item.Constructor);
            }
            Console.ReadLine();
  • 集合操作
Func<string, IEnumerable<Racer>> racersByCar = car => from r in Formula1.GetChampions()
                                                                  from c in r.Cars
                                                                  where c == car
                                                                  orderby r.LastName
                                                                  select r;

            Console.WriteLine("World champion with Ferrari and McLaren");
            foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
            {
                Console.WriteLine(racer);
            }
            Console.ReadLine();
  • 合并
 var racerNames = from r in Formula1.GetChampions()
                             where r.Country == "Italy"
                             orderby r.Wins descending
                             select new
                             {
                                 Name = r.FirstName + " " + r.LastName
                             };

            var racerNamesAndStarts = from r in Formula1.GetChampions()
                                      where r.Country == "Italy"
                                      orderby r.Wins descending
                                      select new
                                      {
                                          LastName = r.LastName,
                                          Starts = r.Starts
                                      };

            var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ",starts: " + second.Starts);
            foreach (var r in racers)
            {
                Console.WriteLine(r);
            }
            Console.ReadLine();
  • 分区
 ;
            int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() / (double)pageSize);

            ; page < numberPages; page++)
            {
                Console.WriteLine("Page {0}", page);

                var racers = (from r in Formula1.GetChampions()
                              orderby r.LastName, r.FirstName
                              select r.FirstName + " " + r.LastName).Skip(page * pageSize).Take(pageSize);

                foreach (var name in racers)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine();
            }
            Console.ReadLine();
  • 聚合操作符
var query = from r in Formula1.GetChampions()
                        let numberYears = r.Years.Count()

                        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);
            }

            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();
            foreach (var country in countries)
            {
                Console.WriteLine("{0} {1}", country.Country, country.Wins);
            }
            Console.ReadLine();
  • 转换操作符

在迭代中使用查询时,查询才会执行,使用转换操作符会立即执行查询,把查询结果放在数组、列表或字典中。

 List<Racer> racers = (from r in Formula1.GetChampions()

                                  orderby r.Starts descending
                                  select r).ToList();
            foreach (var racer in racers)
            {
                Console.WriteLine("{0} {0:S}", racer);
            }

            Console.ReadLine();

*如果在非类型化集合上使用LINQ查询,为了定义强类型化的查询,就可以使用Cast()方法。

  • 生成操作符
, ).Select(n => n * );
            foreach (var item in values)
            {
                Console.WriteLine("{0} ", item);
            }

            Console.ReadLine();