c#中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>接口提供了各种扩展方法(扩展方法在https://www.jb51.net/article/243984.htm介绍到),以便用户在实现了该接口的任意集合上使用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; }
          }

到此这篇关于c#中LINQ的基本用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 全面分析c# LINQ

    大家好,这是 [C#.NET 拾遗补漏] 系列的第 08 篇文章,今天讲 C# 强大的 LINQ 查询.LINQ 是我最喜欢的 C# 语言特性之一. LINQ 是 Language INtegrated Query 单词的首字母缩写,翻译过来是语言集成查询.它为查询跨各种数据源和格式的数据提供了一致的模型,所以叫集成查询.由于这种查询并没有制造新的语言而只是在现有的语言基础上来实现,所以叫语言集成查询. 一些基础 在 C# 中,从功能上 LINQ 可分为两类:LINQ to Object 和 L

  • 带你一文了解C#中的LINQ

    目录 前言 LINQ的根基 IEnumerable和IEnumerator LINQ的基本用法 扩展方法在LINQ的应用:LINQ的流式语法 LINQ的查询表达式:LINQ的查询语法 LINQ的延迟执行:IQueryable 附:将内存中对象转换为 XML 参考 源码 总结 前言 本文主要的是泛谈LINQ是啥?以及常见的用法大纲如下: LINQ的那些根基 LINQ的一些基本用法 LINQ的根基 IEnumerable和IEnumerator 为啥能够被foreach? 实际上,能够被foreac

  • c# 动态构建LINQ查询表达式

    作者:精致码农 出处:http://cnblogs.com/willick 联系:liam.wang@live.com 最近工作中遇到一个这样的需求:在某个列表查询功能中,可以选择某个数字列(如商品单价.当天销售额.当月销售额等),再选择 小于或等于 和 大于或等于 ,再填写一个待比较的数值,对数据进行查询过滤. 如果只有一两个这样的数字列,那么使用 Entity Framework Core 可以这么写 LINQ 查询: public Task<List<Product>> Ge

  • C# LINQ的基本使用方法示例

    LINQ是什么? LINQ是Language Integrated Query(语言集成查询的缩写), 微软官方 对其的描述: 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 基本用法是什么? (我目前也只会最基本的用法..) LINQ查询操作由三个不同的操作组成: 获取数据源 创建查询 执行查询 下面我将用我学习时用的一个小例子来演示. 有两个数据源:武林高手的集合和武林绝学的集合. 我用的是两个集合,实际上不只是集合可以作为数据源 微软官方文档提到: 上例中

  • C# LINQ查询表达式及对应LAMBDA表达式的用法

    C#编程语言非常优美,我个人还是非常赞同的.特别是在学习一段时间C#后发现确实在它的语法和美观度来说确实要比其它编程语言强一些(也可能是由于VS编译器的加持)用起来非常舒服,而且对于C#我觉得他最优美之处不仅仅是语法糖方面还有就是体现在LINQ和Lambda表达式. 本篇文简单介绍一下关于C#当中LINQ表达式和其对应的Lambda表达式的用法,关于这两部分内容的相关参考资料: 人民邮电出版社<C#程序设计及应用教程>(第3版) 博客:<c# Linq查询> 同时在介绍的时候我会尽

  • C# 并行和多线程编程——并行集合和PLinq

    在上一篇博客,我们学习了Parallel的用法.并行编程,本质上是多线程的编程,那么当多个线程同时处理一个任务的时候,必然会出现资源访问问题,及所谓的线程安全.就像现实中,我们开发项目,就是一个并行的例子,把不同的模块分给不同的人,同时进行,才能在短的时间内做出大的项目.如果大家都只管自己写自己的代码,写完后发现合并不到一起,那么这种并行就没有了意义. 并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合:微软向的也算周到,没有忘记linq,也推出了linq的并行版本,plinq - P

  • c# Linq查询详解

    c#提供的ling查询极大的遍历了集合的查询过程,且使用简单方便,非常的有用. 下面将分别用简单的例子说明:ling基本查询.延迟查询属性.类型筛选.复合from字句.多级排序.分组查询.联合查询.合并.分页.聚合操作符.并行linq.取消长时间运行的并行ling查询. Lambda表达式简介: /*Lambda表达式:Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数 表达式位于 => 运算符右侧的 lambda 表达式称为"表达式 lambda". * (i

  • c#中LINQ的基本用法(三)

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

  • c#中LINQ的基本用法(二)

    目录 1.筛选 2.用索引筛选 3.类型筛选 4.复合的from子句 5.排序 6.分组 7.对嵌套的对象分组 8.内连接 9.左连接 10.组连接 11.集合操作 12.合并 13.分区 14.聚合操作符 15.转换操作符 16.生成操作符 本文主要介绍LINQ查询操作符 LINQ查询为最常用的操作符定义了一个声明语法.还有许多查询操作符可用于Enumerable类.下面的例子需要用到LINQ基础(一)(https://www.jb51.net/article/244208.htm)的一些代码

  • c#中LINQ的基本用法(一)

    LINQ(Language Integrated Query,语言集成查询),在C#语言中集成了查询语法,可以用相同的语法访问不同的数据源.LINQ提供了不同数据源的抽象层,所以可以使用相同的语法.这里主要介绍LINQ的核心原理和C#中支持C# LINQ查询的语言扩展. 1.语法 使用LINQ查询出来自巴西的所以世界冠军.这里可以使用List<T>类的FindAll()方法,但使用LINQ查询语法更简单 static void LINQQuery() { // var query = from

  • c#中LINQ的基本用法实例

    一.什么是LINQ LINQ(读音link)代表语言集成查询(Language Integrated Query),是.NEt框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合,使用它,你可以从数据库.程序对象的集合以及XML文档中查询数据 下面一个简单的示例,可以查询数组中小于8的数字并输出. 一般步骤:获取数据源.创建查询.执行查询.需要注意的是,尽管查询在语句中定义,但直到最后的foreach语句请求其结果的时候才会执行 using System; using System.C

  • Linq中ToList()和CopyToDataTable()用法详解

    最近在项目中使用了Linq,想把Linq的查询结果直接转换成DataTable对象,通过查找发现Linq有一个CopyToDataTable<T>的泛型方法,该方法只能在T是DataRow的情况下使用,发现了这个方法以后就直接在项目中使用了,但是在使用的过程中发现,如果Linq的查询结果不包含任何DataRow对象的时候,使用CopyToDataTable()方法会报错,代码如下: using System; using System.Collections.Generic; using Sy

  • C#中JavaScriptSerializer帮助类用法实例

    本文实例讲述了C#中JavaScriptSerializer帮助类用法.分享给大家供大家参考.具体如下: 关键代码如下: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Web.Script.Serialization; namespace YanZhiwei.DotNet3._5.Utilities.Common {    

  • WinForm中BackgroundWorker控件用法简单实例

    本文实例讲述了WinForm中BackgroundWorker控件用法.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Win

  • C#中while循环语句用法实例详解

    本文实例讲述了C#中while循环语句用法.分享给大家供大家参考.具体实现方法如下: 在C#中while循环是我们经常会用到的一种循环语句,while循环特点是直到条件为零时才跳出循环,当然中间可以利用其它函数直接跳出,对于while的具体用法有必要做一个较为详尽的分析. 先来说Foreach和For的区别,Foreach是针对对象进行遍历的,不需要定义循环次数,但是有个缺点,Foreach遍历取的是只读数据,不能在Foreach中进行对象的增删改,而For循环就可以.这个改成while循环的代

  • C#中backgroundWorker类的用法详解

    1.在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应.解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作.新建线程可以用 Thread 类,可以实现多线程同时操作.简单的方法可以通过 BackgroundWorker 类实现. BackgroundWorker 可以用来更新UI界面,但是通常用来Progressbar(进度条)控件 例如更新UI private void Form1_Load(objec

  • .NET Core中的HttpClientFactory类用法详解

    一.HttpClient使用 在C#中,如果我们需要向某特定的URL地址发送Http请求的时候,通常会用到HttpClient类.会将HttpClient包裹在using内部进行声明和初始化,如下面的代码: using (var httpClient = new HttpClient()) { // 逻辑处理代码 } HttpClient类包含了许多有用的方法,使用上面的代码,可以满足绝大多数的需求,但是如果对其使用不当时,可能会出现意想不到的事情. 上面代码的技术范点:当你使用继承了IDisp

随机推荐