Linq实战案例

此案例参考相关C#书籍;

准备步骤如下:

    public class Racer : IComparable<Racer>, IFormattable
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Wins { get; set; }
        public string Country { get; set; }
        public int Starts { get; set; }
        public IEnumerable<string> Cars { get; set; }
        public IEnumerable<int> Years { get; set; }
        public Racer(string firstName, string lastName, string country, int starts, int wins)
            : this(firstName, lastName, country, starts, wins, null, null)
        {

        }
        public Racer(string firstName, string lastName, string country, int starts, int wins, IEnumerable<int> years, IEnumerable<string> cars)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Country = country;
            this.Starts = starts;
            this.Wins = wins;
            this.Years = years != null ? new List<int>(years) : new List<int>();
            this.Cars = cars != null ? new List<string>(cars) : new List<string>();
        }
        public override string ToString() => $"{FirstName} {LastName}";
        public string ToString(string format) => ToString(format, null);


        public string ToString(string format, IFormatProvider formatProvider)
        {
            switch (format)
            {
                case null:
                case "N":
                    return ToString();
                case "F":
                    return "FirstName";
                case "L":
                    return "LastName";
                case "C":
                    return "Country";
                case "S":
                    return Starts.ToString();
                case "W":
                    return Wins.ToString();
                case "A":
                    return $"{FirstName} {LastName},{Country};starts:{Starts},wins:{Wins}";
                default:
                    throw new FormatException($"Format {format} not supported");
            }
        }

        public int CompareTo(Racer other) => LastName.CompareTo(other?.LastName);

    }

    public class Team
    {
        public string Name { get; set; }
        public IEnumerable<int> Years { get; set; }
        public Team(string name, params int[] years)
        {
            this.Name = name;
            Years = years != null ? new List<int>(years) : new List<int>();
        }
    }

    public static class Formual
    {
        private static List<Racer> _racers;
        public static IList<Racer> GetChampions()
        {
            if (_racers == null)
            {
                _racers = new List<Racer>(40);
                _racers.Add(new Racer("Nino", "Farina", "Italy", 33, 5, new int[] { 1950 }, new string[] { "Alfa Romeo" }));
                _racers.Add(new Racer("Alberto", "Ascari", "Italy", 32, 10, new int[] { 1952, 1953 }, new string[] { "Ferrari" }));
                _racers.Add(new Racer("Juan Manuel", "Fangio", "Argentina", 51, 24, new int[] { 1951, 1954, 1955, 1956, 1957 }, new string[] { "Alfa Remeo", "Maserati", "Mercedes", "Ferrari" }));
                _racers.Add(new Racer("Mike", "Hawthorn", "UK", 45, 3, new int[] { 1958 }, new string[] { "Ferrari" }));
                _racers.Add(new Racer("Phil", "Hill", "USA", 48, 3, new int[] { 1961 }, new string[] { "Ferrari" }));
                _racers.Add(new Racer("John", "Surtees", "UK", 111, 6, new int[] { 1964 }, new string[] { "Ferrari" }));
                _racers.Add(new Racer("Jim", "Clark", "UK", 72, 25, new int[] { 1963, 1965 }, new string[] { "Lotus" }));
                _racers.Add(new Racer("Jack", "Brabham", "Australia", 125, 14, new int[] { 1959, 1960, 1966 }, new string[] { "Cooper", "Brabhm" }));
                _racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8, new int[] { 1967 }, new string[] { "Brabhm" }));
                _racers.Add(new Racer("Graham", "Hill", "UK", 176, 14, new int[] { 1962, 1968 }, new string[] { "BRM", "Lotus" }));
                _racers.Add(new Racer("Jochen", "Rindt", "Austria", 60, 6, new int[] { 1970 }, new string[] { "Lotus" }));
                _racers.Add(new Racer("Jackie", "Stewart", "UK", 99, 27, new int[] { 1969, 1971, 1973 }, new string[] { "Matra", "Tyrrell" }));
            }
            return _racers;
        }
        private static List<Team> _teams;
        public static IList<Team> GetContructorChampions()
        {
            if (_teams == null)
            {
                _teams = new List<Team>()
                {
                    new Team("Vanwall",1958),
                    new Team("Cooper", 1959,1960),
                    new Team("Ferrari", 1961,1964,1975,1976,1977,1979,1982,1983,1999,2000,2001,2002,2003,2004,2007,2008),
                    new Team("BRM", 1962),
                    new Team("Lotus", 1963,1965,1968,1970,1972,1973,1978),
                    new Team("Brabham", 1966,1967),
                    new Team("Matra", 1969),
                    new Team("Tyrrell", 1971),
                    new Team("Mclaren", 1974,1984,1985,1988,1989,1990,1991,1998),
                    new Team("Williams", 1980,1981,1986,1987,1992,1993,1994,1996,1997),
                    new Team("Benetton", 1995),
                    new Team("Renault", 2005,2006),
                    new Team("Brawn GP", 2009),
                    new Team("Red Bull Racing", 2010,2011,2012,2013),
                    new Team("Mercedes", 2014,2015)
            };
            }
            return _teams;
        }
        private static List<Championship> championships;
        public static IEnumerable<Championship> GetChampionships()
        {
            if (championships == null)
            {
                championships = new List<Championship>();
                championships.Add(new Championship
                {
                    Year = 1950,
                    First = "Nino Farina",
                    Second = "Juan Manuel Fangio",
                    Third = "Luigi Fagioli"
                });
                championships.Add(new Championship
                {
                    Year = 1951,
                    First = "Juan Manuel Fangio",
                    Second = "Alberto Ascari",
                    Third = "Froilan Gonzalez"
                });
            }
            return championships;
        }
    }

上面的类作为存储数据的容器,下面是linq的具体使用(具体的操作符说明可以查看我的上一篇博文):

        static void Main(string[] args)
        {
            //1.筛选
            //找出赢得至少15场比赛的英国和奥地利赛车手。
            var query1 = from r in Formual.GetChampions()
                         where (r.Country == "UK" || r.Country == "Austria") && r.Wins > 15
                         select r;
            //1.1索引筛选
            //找出姓氏以A开头、索引为偶数的赛车手
            var query2 = Formual.GetChampions().Where((r, index) => r.LastName.StartsWith("A") && index % 2 != 0);
            //1.2类型筛选
            //取出下面所有string类型的参数
            object[] data = { "1", 2, "3", 4, "5", 6, "7", 8, "9", 10 };
            var query3 = data.OfType<string>();
            //2.复合的From子句
            //筛选驾驶法拉利的所有冠军
            var query4 = from r in Formual.GetChampions()
                         from c in r.Cars
                         where c == "Ferrari"
                         orderby r.LastName
                         select r.FirstName + " " + r.LastName;
            //2.1 使用SelectManay方式替换掉上面的写法
            var query5 = Formual.GetChampions().SelectMany(r => r.Cars, (r, c) => new { Racer = r, Car = c })
                .Where(r => r.Car == "Ferrari")
                .OrderBy(r => r.Racer.LastName)
                .Select(r => r.Racer.FirstName + " " + r.Racer.LastName);
            //3.排序
            //来自英国的赛车手按照赢得比赛的次数进行降序排序
            var query6 = from r in Formual.GetChampions() where r.Country == "UK" orderby r.Wins descending select r;
            //3.1使用ThenBy进行二次排序
            var query7 = Formual.GetChampions().Where(r => r.Country == "UK").OrderBy(r => r.Wins).ThenBy(r => r.FirstName).Take(10);
            //4.分组(group m by m.Country into g)
            //列出每个国家的冠军数
            var query8 = from r in Formual.GetChampions()
                         group r by r.Country into g
                         orderby g.Count() descending, g.Key
                         where g.Count() > 1
                         select new
                         {
                             Country = g.Key,
                             Count = g.Count()
                         };
            //4.1根据国家分组另一种写法
            var query9 = Formual.GetChampions()
                  .GroupBy(r => r.Country)
                  .OrderByDescending(g => g.Count())
                  .ThenBy(g => g.Key)
                  .Where(g => g.Count() > 1)
                  .Select(g => new { Country = g.Key, Count = g.Count() });
            //5.LINQ查询中的变量
            //上面的分组查询Count方法调用了多次。使用let子句可以改变这种形式
            var query10 = from r in Formual.GetChampions()
                          group r by r.Country into g
                          let count = g.Count()
                          orderby count descending, g.Key
                          where count > 1
                          select new
                          {
                              Country = g.Key,
                              Count = count
                          };
            //5.1使用Select方法创建匿名类型
            var query11 = Formual.GetChampions()
                .GroupBy(r => r.Country)
                .Select(g => new { Group = g, Count = g.Count() })
                .OrderByDescending(g => g.Count)
                .ThenBy(g => g.Group.Key)
                .Where(g => g.Count > 1)
                .Select(g => new
                {
                    Country = g.Group.Key,
                    Count = g.Count
                });
            //6.嵌套对象分组
            var query12 = from r in Formual.GetChampions()
                          group r by r.Country into g
                          let count = g.Count()
                          orderby count descending, g.Key
                          where count > 1
                          select new
                          {
                              Country = g.Key,
                              Count = count,
                              Racers = from r1 in g
                                       orderby r1.LastName
                                       select r1.FirstName + " " + r1.LastName
                          };
            foreach (var item in query12)
            {
                Console.WriteLine($"国家:{item.Country},冠军数量:{item.Count}");
                foreach (var info in item.Racers)
                {
                    Console.WriteLine(info);
                }
            }
            //7.内连接
            //查出每年赛车手冠军和车队冠军
            var query13 = from r in Formual.GetChampions()
                          from yr in r.Years
                          select new
                          {
                              Year = yr,
                              Name = r.FirstName + " " + r.LastName
                          } into s1
                          join s2 in
                          from t in Formual.GetContructorChampions()
                          from yt in t.Years
                          select new
                          {
                              Year = yt,
                              Name = t.Name
                          }
                          on s1.Year equals s2.Year
                          orderby s2.Year
                          select new
                          {
                              Year = s1.Year,
                              Racer = s1.Name,
                              Team = s2.Name
                          };
            //另一种方式的写法
            var query14 = Formual.GetChampions()
                .SelectMany(m => m.Years, (m, y) => new { Racer = m, Year = y })
                .Join(Formual.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);
            //8.左外连接(DefaultIfEmpty)
            var query15 = from r in Formual.GetChampions()
                          from yr in r.Years
                          select new
                          {
                              Year = yr,
                              Name = r.FirstName + " " + r.LastName
                          }
                          into s1
                          join s2 in from t in Formual.GetContructorChampions()
                                     from yt in t.Years
                                     select new
                                     {
                                         Year = yt,
                                         Name = t.Name
                                     }
                                     on s1.Year equals s2.Year into rt
                          from s2 in rt.DefaultIfEmpty()
                          orderby s1.Year
                          select new
                          {
                              Year = s1.Year,
                              Champion = s1.Name,
                              Constructor = s2 == null ? "no constructor championship" : s2.Name
                          };
            //9.组连接
            //就是join 关联不止是一个也可能包含多个
            var query16 = Formual.GetChampionships()
                .SelectMany(cs => new List<RacerInfo>()
                {
                    new RacerInfo{
                        Year =cs.Year,
                        Position = 1,
                        FirstName =cs.First.FirstName(),//定义的扩展方法
                        LastName = cs.First.LastName()//定义的扩展方法
                    },
                     new RacerInfo{
                        Year =cs.Year,
                        Position = 2,
                        FirstName =cs.Second.FirstName(),//定义的扩展方法
                        LastName = cs.Second.LastName()//定义的扩展方法
                    },
                      new RacerInfo{
                        Year =cs.Year,
                        Position = 3,
                        FirstName =cs.Third.FirstName(),//定义的扩展方法
                        LastName = cs.Third.LastName()//定义的扩展方法
                    }
                });
            var query17 = from r in Formual.GetChampions()
                          join r2 in query16 on
                          new
                          {
                              FirstName = r.FirstName,
                              LastName = r.LastName
                          }
                          equals
                          new
                          {
                              FirstName = r2.FirstName,
                              LastName = r2.LastName
                          }
                          into yearResults
                          select new
                          {
                              FirstName = r.FirstName,
                              LastName = r.LastName,
                              Wins = r.Wins,
                              Starts = r.Starts,
                              Results = yearResults
                          };
            foreach (var item in query17)
            {
                Console.WriteLine($"FirstName:{item.FirstName};LastName:{item.LastName};Wins:{item.Wins};Starts:{item.Starts}");
                foreach (var info in item.Results)
                {
                    Console.WriteLine(info.LastName);
                }
            }
            //10.集合操作(Distinct()、Union()、Intersect()和Except())
            //交集Intersect()
            Func<string, IEnumerable<Racer>> func = car => from r in Formual.GetChampions() from c in r.Cars where c == car orderby r.LastName select r;
            foreach (var item in func("Ferrari").Intersect(func("Mercedes")))
            {
                Console.WriteLine(item);
            }
            //11.合并(Zip(集合,委托(第一个参数和第二个参数合并)))
            var query18 = from r in Formual.GetChampions()
                          where r.Country == "Italy"
                          orderby r.Wins descending
                          select new
                          {
                              Name = r.FirstName + " " + r.LastName
                          };
            var query19 = from r in Formual.GetChampions()
                          where r.Country == "Argentina"
                          orderby r.Wins descending
                          select new
                          {
                              LastName = r.LastName,
                              Starts = r.Starts
                          };
            var query20 = query18.Zip(query19, (f, s) => f.Name + ",Starts:" + s.Starts);
            //12.分区(Take()、Skip())
            int pageSize = 5;
            int pageNum = (int)Math.Ceiling(Formual.GetChampions().Count() / (double)pageSize);
            Func<int, int, IEnumerable<Racer>> res = (x, y) => (from r in Formual.GetChampions() orderby r.LastName ascending, r.FirstName ascending select r).Skip(x * y).Take(y);
            for (int i = 0; i < pageNum; i++)
            {
                Console.WriteLine($"Page {i}");
                foreach (var item in res(i, pageSize))
                {
                    Console.WriteLine(item);
                }
            }
            //13.聚合操作(Count、Sum、Min、Max、Average和Aggregate操作符)
            //案例如下,其他聚合函数类似
            var query21 = from r in Formual.GetChampions()
                          group r by r.Country into c
                          select new
                          {
                              Country = c.Key,
                              Wins = (from r1 in c select r1.Wins).Sum()
                          };
            //14.转换操作符(ToList()、ToLookUp())
            var query22 = (from r in Formual.GetChampions()
                           from c in r.Cars
                           select new
                           {
                               Car = c,
                               Racer = r
                           }).ToLookup(cr => cr.Car, cr => cr.Racer);
            foreach (var item in query22["Ferrari"])
            {
                Console.WriteLine(item);
            }
            //15.生成操作符(Range()、Empty()、Repeat())
            var query23 = Enumerable.Range(1, 20).Select(n => n * 5);
            foreach (var item in query23)
            {
                Console.WriteLine(item);
            }
            //16.并行查询
            var query24 = from r in Formual.GetChampions().AsParallel() select r;
            //17.分区器
            var query25 = from r in Partitioner.Create(Formual.GetChampions(), true).AsParallel() select r;
            //18.取消
            var cts = new CancellationTokenSource();
            var query26 = from r in Formual.GetChampions().AsParallel().WithCancellation(cts.Token) select r;
            string input = Console.ReadLine();
            if (input.ToLower().Equals("y"))
            {
                cts.Cancel();
            }
        }

具体的执行方式 可以用foreach将数据循环出来查看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双叶红于二月花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值