LINQ基础(一)

  LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源。
  LINQ提供了不同数据源的抽象层,所以可以使用相同的语法。
  这里主要介绍LINQ的核心原理和C#中支持C# LINQ查询的语言扩展。

1.语法
  使用LINQ查询出来自巴西的所以世界冠军。这里可以使用List<T>类的FindAll()方法,但使用LINQ查询语法更简单  

    static void LINQQuery()
        {
          //
          var query = from r in Formula1.GetChampions()
                      where r.Country == "Brazil"
                      orderby r.Wins descending
                      select r;

          foreach (var r in query)
          {
            Console.WriteLine("{0:A}", r);
          }

        }    

  变量query只指定了LINQ查询。该查询不是通过这个赋值语句执行的,而是使用foreach循环访问查询时执行的。

2.扩展方法
  编译器会转换LINQ查询,以调用方法而不是LINQ查询。LINQ为IEnumerable<T>接口提供了各种扩展方法(扩展方法在http://www.cnblogs.com/afei-24/p/6703843.html介绍到),以便用户在实现了该接口的任意集合上使用LINQ查询。
  定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。只需要导入这个名称空间,就打开了这个类的扩展方法的作用域。下面是Where()扩展方法的实现代码:

    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)
        {
            foreach(TSource item in source)
            {
                if(predicate(item))
                {
                    yield return item;
                }

            }
        }

  因为Where()作为一个泛型方法,所以它可以用于包含在集合中的任意类型。实现了IEnumerable<T>接口的任意集合都支持它。

3.推迟查询的执行
  前面提到,在运行期间定义LINQ查询表达式时,查询不会运行。查询在迭代数据项时才会运行。
  举个例子:  

    static void DeferredQuery()
        {
          var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };

          var namesWithJ = from n in names
                           where n.StartsWith("J")
                           orderby n
                           select n;

          Console.WriteLine("First iteration");
          foreach (string name in namesWithJ)
          {
            Console.WriteLine(name);
          }
          Console.WriteLine();

          names.Add("John");
          names.Add("Jim");
          names.Add("Jack");
          names.Add("Denny");

          Console.WriteLine("Second iteration");
          foreach (string name in namesWithJ)
          {
            Console.WriteLine(name);
          }

        }

  输出:
  
  因为查询在迭代时才执行,所以在第一次输出后有添加项再输出,会显示又添加的项。

  但在调用方法ToArray(),ToList等方法时,不会延迟执行:  

    static void NotDeferredQuery()
        {
            var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };

            var namesWithJ = (from n in names
                             where n.StartsWith("J")
                             orderby n
                             select n).ToList();

            Console.WriteLine("First iteration");
            foreach (string name in namesWithJ)
            {
                Console.WriteLine(name);
            }
            Console.WriteLine();

            names.Add("John");
            names.Add("Jim");
            names.Add("Jack");
            names.Add("Denny");

            Console.WriteLine("Second iteration");
            foreach (string name in namesWithJ)
            {
                Console.WriteLine(name);
            }

        }

  输出:
  

下面是用到的类,后续的也需要用到这些代码。

//这个类创建需要的列表
        public static class Formula1
          {
            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 Romeo", "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", "Brabham" }));
                racers.Add(new Racer("Denny", "Hulme", "New Zealand", 112, 8,           new int[] { 1967 }, new string[] { "Brabham" }));
              }

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

            private static List<Championship> championships;
            //返回GetChampionships类型的集合
            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"
                });
                championships.Add(new Championship
                {
                  Year = 1952,
                  First = "Alberto Ascari",
                  Second = "Nino Farina",
                  Third = "Piero Taruffi"
                });
                championships.Add(new Championship
                {
                  Year = 1953,
                  First = "Alberto Ascari",
                  Second = "Juan Manuel Fangio",
                  Third = "Nino Farina"
                });
                championships.Add(new Championship
                {
                  Year = 1954,
                  First = "Juan Manuel Fangio",
                  Second = "Froilan Gonzalez",
                  Third = "Mike Hawthorn"
                });
                championships.Add(new Championship
                {
                  Year = 1955,
                  First = "Juan Manuel Fangio",
                  Second = "Stirling Moss",
                  Third = "Eugenio Castellotti"
                });
                championships.Add(new Championship
                {
                  Year = 1956,
                  First = "Juan Manuel Fangio",
                  Second = "Stirling Moss",
                  Third = "Peter Collins"
                });

              }
              return championships;
            }
        }
//车手类

    [Serializable]
      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)
        {
          this.FirstName = firstName;
          this.LastName = lastName;
          this.Country = country;
          this.Starts = starts;
          this.Wins = wins;
          this.Years = new List<int>(years);
          this.Cars = new List<string>(cars);
        }
        //单值属性
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Country { get; set; }
        public int Wins { get; set; }
        public int Starts { get; set; }
        //多值属性,车手可能多次获得冠军,所在的车队也可能不同
        public IEnumerable<string> Cars { get; private set; }
        public IEnumerable<int> Years { get; private set; }

        public override string ToString()
        {
          return String.Format("{0} {1}", FirstName, LastName);
        }

        public int CompareTo(Racer other)
        {
          if (other == null) return -1;
          return string.Compare(this.LastName, other.LastName);
        }

        public string ToString(string format)
        {
          return 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 String.Format("{0} {1}, {2}; starts: {3}, wins: {4}",
                    FirstName, LastName, Country, Starts, Wins);
            default:
              throw new FormatException(String.Format("Format {0} not supported", format));
          }
        }
      }
//获得冠军的车队
        [Serializable]
        public class Team
        {
            public Team(string name, params int[] years)
            {
                this.Name = name;
                this.Years = new List<int>(years);
            }
            public string Name { get; private set; }
            public IEnumerable<int> Years { get; private set; }
        }

        //获奖选手和年份
          public class Championship
          {
            public int Year { get; set; }
            public string First { get; set; }
            public string Second { get; set; }
            public string Third { get; set; }
          }
时间: 2024-11-05 19:30:49

LINQ基础(一)的相关文章

LINQ基础(三)

一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上. 尽管Enumerable类给IEnumerable<T>接口定义了扩展方法,但ParallelEnumerable类的大多数扩展方法是ParallerQuery<TSource>类的扩展.例如,AsParallel()方法,它扩展了IEnumerable<T>接口,返回ParallelQuery<T>类,所以正常的集合类可

LINQ基础(二)

本文主要介绍LINQ查询操作符 LINQ查询为最常用的操作符定义了一个声明语法.还有许多查询操作符可用于Enumerable类. 下面的例子需要用到LINQ基础(一)(http://www.cnblogs.com/afei-24/p/6841361.html)的一些代码 1.筛选 LINQ查询使用where子句添加条件表达式来筛选,where子句可以合并多个表达式. var racers = from r in Formula1.GetChampions() where r.Wins>15 &

20.C#LINQ基础和简单使用(十一章11.1-11.2)

终于看到了第11章,之前虽然也有看过,但没有太仔细,在工作中也偶尔会使用,但不明白其中的原理,那现在就来讲讲LINQ,做一做书虫~~ 首先先了解下LINQ的三个要点: LINQ不能把非常复杂的查询表达式转换成一行代码 使用LINQ不意味着你从此不再需要使用SQL LINQ不可能魔法般地让你成为架构天才 序列是LINQ的基础,在你看到一个查询表达式的时候,应该要想到它所涉及的序列:一开始总是存在至少一个序列,且通常在中间过程会转换成其他序列,也可能和其他序列连接在一起. 1 class Car 2

LinQ 基础

Linq to Sql:      LINQ TO SQL是包含在.NET Framework 3.5 版中的一种 O/RM 组件(对象关系映射),O/RM 允许你使用 .NET 的类来对关系数据库进行建模. 数据库访问技术包括:         (1)ADO.NET(基础)   (2)EF框架(集成)   (3)Linq(微软高集成) Linq:高集成化的数据访问类,它会自动映射数据库结构,将表名完整映射成为类名,将列名完整映射成字段名 1.LinQ创建   新建-选择Linq to Sql-

2017-6-1 Linq 基础查询 (增删改查)

用小型人员管理系统的项目实战来练习linq的基础增删改查: using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// users 的摘要说明 /// </summary> public partial class users { public string sexstr { get { return Convert.ToBoolean(

Linq基础语法详细

闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些linq新手,如果有其它疑问,可以进右上角群,进行交流探讨,谢谢. 开门见山 读这篇文章之前,我先说下,每一种搜索结果集,我都以三种方式变现出来,为啦更好的理解,希望不要嫌我啰嗦. 1.简单的linq语法 //1 var ss = from r in db.Am_recProScheme select r; //2 var ss1 = db.Am_recProScheme; //3 string sssql =

linq基础

linq掌握(1.linq基本 2.lambda表达式 3.linq方法Select()/Where()/OrderBy()/GroupBy()  4.linq语句 5.理解查询语句与查询方法的关系 6.掌握各种高级查询方法 7.理解 LINQ to SQL )    命名空间:System.Linq;linq :  它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据.   语法:1) from 临时变量 in 实现IEnumerable<T>接口的对象     

Linq基础总结

隐式类型: 在隐式类型出现之前, 我们在声明一个变量的时候, 总是要为一个变量指定他的类型甚至在foreach一个集合的时候,也要为遍历的集合的元素,指定变量的类型隐式类型的出现,程序员就不用再做这个工作了. 匿名类型: 匿名类型是C#3.0提供的一个新的语法机制,它使用new操作符和匿名对象初始化器能够创建一个新的对象.这个新创建的对象就是一个匿名类型对象. 隐形数组: 隐形数组和匿名类型对象比较相似.                      隐形数组使用var关键字和数组初始化器创建,且数

【2017-06-01】Linq基础+Lambda表达式实现对数据库的增删改查

一.Linq to sql 类 高集成化的数据库访问技术 使用Linq可以代替之前的Ado.Net.省去了自己敲代码的实体类和数据访问类的大量工作. 实体类: 添加一个Linq to sql 类 ----选择要使用的数据库---- 拖入要使用的表  就相当于实体类建完了. 如果进行属性扩展,在App_Code下添加类,类名同表名一致.将该类在访问修饰符后加上partial,将该类定为实体类的一部分 数据访问类: 不用在App_Code下再建数据访问类了. 直接在使用数据访问类的地方用数据库上下文

Linq基础增删改查

使用Linq时要注意一下问题:1.创建Linq连接后生成的dbml文件不要变动,生成的表不要碰,拖动表也会造成数据库连接发生变动,需要重新保存.2.属性拓展的使用:添加一个新的类,不要在dbml中添加属性拓展,一旦数据库变动,属性拓展类就会失效.3.使用Linq获取的数据都是?int,?string等?数据类型,意思是也有可能为空,这时候操作数据需要先把数据类型转化成int,string等数据类型. 在这里操作数据库用到了lambda表达式,是一种匿名函数,使用lambda表达式自动带有防攻击,