C#中的LINQ查询

开发工具与关键技术:LINQ查询

作者:邓崇富

撰写时间:2019 年6 月 24 日

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LINQ概述:

LINQ(Language Integrated Query,语言集成查询)在C#编程语言中集成了查询语法,可以用相同的语法访问不同的数据源,LINQ提供了不同数据源的抽象层,所以可以使用相同的语法。

列表和实体:

为了下面的LINQ查询演示,需要准备一些实体和列表来存放一些数据,查询的数据在一个包含1950至2015一级方程式锦标赛的集合上。

对于实体,定义类型Racer。Racer定义了几个属性和一个重载的ToString()方法,该方法以字符串格式显示赛车手。这个类实现了IFormattable接口,,以支持格式字符串的不同变体,这个类还实现了IComparable<Racer>接口,它根据Lastname为一组赛车手排序。为了执行更高级的查询,Racer类不仅包含单值属性,如Lastname、Wins、Country和Starts,还包含多值属性,如Cars和Years。Years属性列出了赛车手获得冠军的年份。一些赛车手曾多次获得冠军。Cars属性用于列出赛车手在获得冠军的年份中使用的所有车型。

详细代码如下:

namespace Wrox.ProCSharp.LINQ

{

    public class Racer:IComparable<Racer>,IFormattable

    {

       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)

        {

            FirstName = firstName;

            LastName = lastName;

            Country = country;

            Starts = starts;

            Wins = wins;

            Years = years != null ? new List<int>(years) : new List<int>();

            Cars = cars != null ? new List<string>(cars) : new List<string>();          

        }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Country { get; set; }

        public int Starts { get; set; }

        public int Wins { get; set; }

        public IEnumerable<int> Years { get; set; }

        public IEnumerable<string> Cars { get; set; }

 

        public override string ToString() => $"{FirstName}{LastName}";

 

        public int CompareTo(Racer other) => LastName.CompareTo(other?.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");                   

            }

         }

      }

}

第二个实体类是Team。这个类包含车队冠军的名字和获得冠军的年份。与赛车手冠军类似,针对一年中最好的车队也有一个冠军奖项。

详细代码如下:

namespace Wrox.ProCSharp.LINQ

{

    public class Team

    {

        public Team(string name,params int[] years)

        {

            Name = name;

            Years = years != null ? new List<int>(years) : new List<int>();

        }

        public string Name { get;}

        public IEnumerable<int> Years { get; }

      }

}

Formulal类在GetChampions()方法中返回一组赛车手。这个列表包含了1950至2015年之间的所有一级方程式冠军。详细代码如下:

public static class Formulal

    {

        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", 33, 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 Romeo","Maserati","Mercedes","Ferrari" })

                //..........

            }

            return _racers;

          }

    }

      对于后面在多个列表的执行的查询,GetContructorChampions()方法返回所有的车队冠军的列表,车队冠军是从1958年开始设立的。详细代码如下:

       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),

                    new Team("BRM",1962),

                    new Team("Lotus",1963,1965,1968,1970,1972,1973,1978),

                    new Team("Brabham",1966,1967)

                    //................

                };

            };

            return _teams;

        }

 列表和实体准备好后,下面进行LINQ查询,例如,查询出来自巴西的所有世界冠军,并按照夺冠次数排序。为此可以使用List<T>类的方法,如FindAll()和Sort()方法。而使用LINQ的语法非常简单。代码如下:

        private static void Lin1Query()

        {

            var query = from r in Formulal.GetChampions()

                        where r.Country == "Brazil"

                        orderby r.Wins descending

                        select r;

            foreach (Racer r in query)

            {

                writeLine($"{r:A}");

            }

      }

是一个LINQ查询。字句from、where、orderby、descending和select 都是这个查询中预定义的关键。查询表达式必须以from字句开头,以select或group字句结束。在这两个字句之间,可以使用where、orderby、join、let和其他from字句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值