Linq to Object 的简单使用示例

   语言集成查询 (LINQ) 是 Visual Studio 2008 中引入的一组功能,可为 C# 和 Visual Basic 语言语法提供强大的查询功能。 LINQ 引入了标准易学的数据查询和更新模式,可以扩展该方法来支持任何类型的数据存储。 Visual Studio 包括 LINQ 提供程序集,后者支持将 LINQ 与 .NET Framework 集合、SQL Server 数据库、ADO.NET 数据集和 XML 文档结合使用。

  LINQ特有的编程结构:

  1. 隐式类型本地变量:C#的var关键字允许定义不显式指定实际数据类型的本地变量。不过由于编译器将根据初始值推断其数据类型,所有该变量仍然是强类型的。
  2. 对象和集合初始化语法:它允许我们在创建类或结构变量的同时设置其属性。
  3. Lambda表达式:C#Lambda操作符(=>)可以用来构建Lambda表达式,并且在调用以强类型的委托作为参数的方法时,也十分有用。
  4. 扩展方法:C#扩展方法不使用子类就能够像已知类中添加新的功能。同样,它还可以向不能有子类的密封类和结构中添加新的功能。在编写扩展方法时,第一个参数必须使用this限定符,用来表示被扩展的类型。扩展方法只能定义在静态类中,并且必须使用static关键字声明为静态方法。
  5. 匿名类型:该特性可以快速建立数据的“结构”,编译器将根据名称/值对的结合在编译时生成新的类。该类型是基于值的语义构建的,因此System.object中的每个虚方法都要重写。要定义一个匿名类型,可以声明一个隐式类型变量,并使用对象初始化语法指定数据的结构。

图是从Linq In Action 中截的。

  下面介绍下Linq To Object:(查询内存中的集合)

这是我们查询所用的数据源,(Linq To Action中的)

using System;
using System.Collections.Generic;
using System.Text;

namespace LinqInAction.LinqBooks.Common
{
  static public class SampleData
  {
    static public Publisher[] Publishers =
    {
      new Publisher {Name="FunBooks"},
      new Publisher {Name="Joe Publishing"},
      new Publisher {Name="I Publisher"}
    };

    static public Author[] Authors =
    {
      new Author {FirstName="Johnny", LastName="Good"},
      new Author {FirstName="Graziella", LastName="Simplegame"},
      new Author {FirstName="Octavio", LastName="Prince"},
      new Author {FirstName="Jeremy", LastName="Legrand"}
    };

    static public Subject[] Subjects =
    {
      new Subject {Name="Software development"},
      new Subject {Name="Novel"},
      new Subject {Name="Science fiction"}
    };

    static public Book[] Books =
    {
      new Book {
        Title="Funny Stories",
        Publisher=Publishers[0],
        Authors=new[]{Authors[0], Authors[1]},
        PageCount=101,
        Price=25.55M,
        PublicationDate=new DateTime(2004, 11, 10),
        Isbn="0-000-77777-2",
        Subject=Subjects[0]
      },
      new Book {
        Title="LINQ rules",
        Publisher=Publishers[1],
        Authors=new[]{Authors[2]},
        PageCount=300,
        Price=12M,
        PublicationDate=new DateTime(2007, 9, 2),
        Isbn="0-111-77777-2",
        Subject=Subjects[0]
      },
      new Book {
        Title="C# on Rails",
        Publisher=Publishers[1],
        Authors=new[]{Authors[2]},
        PageCount=256,
        Price=35.5M,
        PublicationDate=new DateTime(2007, 4, 1),
        Isbn="0-222-77777-2",
        Subject=Subjects[0]
      },
      new Book {
        Title="All your base are belong to us",
        Publisher=Publishers[1],
        Authors=new[]{Authors[3]},
        PageCount=1205,
        Price=35.5M,
        PublicationDate=new DateTime(2006, 5, 5),
        Isbn="0-333-77777-2",
        Subject=Subjects[2]
      },
      new Book {
        Title="Bonjour mon Amour",
        Publisher=Publishers[0],
        Authors=new[]{Authors[1], Authors[0]},
        PageCount=50,
        Price=29M,
        PublicationDate=new DateTime(1973, 2, 18),
        Isbn="2-444-77777-2",
        Subject=Subjects[1]
      }
    };
  }
}

  一、概述

LINQ to OBJECT是用于操作内存对象的LINQ编程接口,包含了大量的查询操作符,针对内存中的集合对象进行操作。LINQ TO OBJECT的大部分操作是针对序列的。标准查询操作符本质是一些扩展方法。

  二、延时标准查询操作符

    I、延时标准查询操作符是指具备延时查询特性的标准查询操作符,这些操作符构成了LINQ TO OBJECT编程接口的最主要内容。

主要包括:(以下示例中,一般第一个方法为Linq扩展方法,第二个方法为查询表达式语法)

  • Where:根据谓词对源序列的内容进行筛选,类似于SQL中的where子句。

    •             var books = SampleData.Books.Where(b => b.Price > 20);
      
                  var books1 = from book in SampleData.Books
                               where book.Price > 30
                               select book;
                  //多条件直接用“&&”或者“||”来组合
                  var book2 = SampleData.Books.Where(b => b.Price > 20 && b.PageCount > 500);

  • Select:投影运算符对应SQL中的“select 列名”子句
    • var books = SampleData.Books.GroupBy(book => book.Publisher).Select(publisherBooks => new
                  {
                      Publisher = publisherBooks.Key.Name,
                      books = publisherBooks
                  });
      
      var books = from publisher in SampleData.Publishers
                              from book in SampleData.Books
                              select new
                              {
                                  Correct = publisher == book.Publisher,
                                  Publisher = publisher.Name,
                                  Book = book.Title
                              };

  • SelectMany:SelectMany操作符实际上实现的是相关数据的交叉连接操作。它根据lambda表达式从一对多的序列中返回指定的属性。
    • var authors = SampleData.Books.SelectMany(book => book.Authors).Distinct().Select(author => author.FirstName + "      " + author.LastName);
      
      var authors2 =
            SampleData.Books.SelectMany(book => book.Authors)
              .Select(author => author.FirstName + "      " + author.LastName);

  • Take:Take是从序列中获取元素的个数;var books1 = SampleData.Books.Take(2);//去前两个
  • Skip:Skip是从序列中跳过元素的个数;var books2 = SampleData.Books.Skip(1).Take(2);//跳过第一个,取前两个
  • TakeWhile:条件抓取,从序列第一个元素开始依次判断,只要满足条件就进行下个元素判断,直到不满足条件的元素为止,返回此元素之前的序列 ;
    • var book1 = SampleData.Books.TakeWhile(b => b.Price > 10);
  • SkipWhile:条件跳过,从序列第一个元素开始依次判断,一直跳到不满足条件的元素为止,返回此元素及此元素之后的序列 ;
    • var book2 = SampleData.Books.SkipWhile(b => b.Price < 15).TakeWhile(b => b.Price > 10);
  • Concat:Concat运算符用来把两个序列连接到一个序列中,它类似于SQL中的关系或or运算符。
    • var bookTitles = SampleData.Books.Select(b => b.Title);
      var authorNames = SampleData.Authors.Select(a => a.FirstName);
      var temp = bookTitles.Concat(authorNames);
  • OrderBy:升序排序
    • var books = SampleData.Books.OrderBy(book=>book.Publisher.Name).ThenByDescending(book=>book.Price).ThenBy(book=>book.Title).Select(book => new { Publisher = book.Publisher.Name, book.Price, book.Title });
  • OrderByDescending:降序排序
  • ThenBy:在OrderBy或OrderByDescending后实现多级排序中实现
  • ThenByDescending:在OrderBy或OrderByDescending后实现多级排序中实现
  • Reverse:降序排序
  • Join、GroupJoin::Join和GroupJoin操作符是把两个相互独立的对象通过关键属性关联起来。这种对象与对象的关联与SQL中的Join关联语法上有些不同。
      1.LinQ的Join不支持SQL-92中的一些比较运算符,如>、<、<>等。它只支持相等运算符
      2.在On子句中不能使用=来实现两个对象之间的关联,需要使用Equals运算符。
    • var books = from publisher in SampleData.Publishers
                              join book in SampleData.Books
                                  on publisher equals book.Publisher
                              select new { Publisher = publisher.Name, Books = book.Title };
      var books2 = SampleData.Publishers.Join(SampleData.Books, publisher => publisher, book => book.Publisher,
                      (publisher, book) => new { Publisher = publisher.Name, Book = book.Title });
      //Join 实现 Left Join
      var books = from publisher in SampleData.Publishers
                              join book in SampleData.Books on publisher equals book.Publisher into publisherBooks
                              from book in publisherBooks.DefaultIfEmpty()
                              select new
                              {
                                  Publisher = publisher.Name,
                                  Book = book == default(Book) ? "no books" : book.Title
                              };

  • GroupBy:分组操作符GroupBy用来按照元素的某个属性来对序列中的元素进行分组。类似于SQL中的group by 子句,但它是对象的序列,还可以获取每组中的每个元素对象。
    • var books = SampleData.Books.GroupBy(book => book.Publisher).Select(publisherBooks => new
                  {
                      Publisher = publisherBooks.Key.Name,
                      books = publisherBooks
                  });
      var books = from book in SampleData.Books
                              group book by book.Publisher into publisherBooks
                              select new
                              {
                                  Publisher = publisherBooks.Key.Name,
                                  books = publisherBooks,
                                  Count = publisherBooks.Count()
                              };

  • Distinct:Distinct操作符用来把序列中重复的值移除掉,类似于SQL中的Distinct
    • var bookTitles = SampleData.Books.Select(b => b.Title).Distinct();
  • Union:Union操作符取两个具有相同结构的集合并集,如果两集合中有相同元素,则会自动滤去重复内容。而前面所讲的Concat操作符只是将两个集合进行合并,并不过滤重复元素。
    • var bookTitles = SampleData.Books.Select(b => b.Title);
      var authorNames = SampleData.Authors.Select(a => a.FirstName);
      var temp = bookTitles.Union(authorNames);
  • Intersect:Intersect操作符是取两个具有相同结构的集合的交集部份。
    • var bookTitles = SampleData.Books.Select(b => b.Title);
      var authorNames = SampleData.Authors.Select(a => a.FirstName);
      var temp = bookTitles.Intersect(authorNames);
  • Except:Except操作符是从一个集合中取另一个集合的差集,即从集合A中取出集合B中不包含的元素。
    • var bookTitles = SampleData.Books.Select(b => b.Title);
      var authorNames = SampleData.Authors.Select(a => a.FirstName);
      var temp = bookTitles.Except(authorNames);
  • Cast
    •             ArrayList booksList = new ArrayList(SampleData.Books);
      
                  var query = from book in booksList.Cast<Book>()
                      where book.PageCount > 150
                      select new
                      {
                          book.Title,
                          book.PageCount
                      };
      
                  var query2 = from Book book in booksList
                              where book.PageCount > 150
                              select new
                              {
                                  book.Title,
                                  book.PageCount
                              };

    II、非延时标准查询操作符

非延时标准查询操作符是指不具备昝查询特性的标准查询操作符,这些操作符一般用于辅助延时标准查询操作符使用。

主要包括:

  • TOArray:把集合转换为数组形式
  • ToList:把集合转换为数组形式
  • ToDictionary:把集合转换成Dictionary<TKey,TElement>类型的集合,它每个元素的value值是原集合中的一个元素对象。
    • Dictionary<string, Book> books = SampleData.Books.ToDictionary(book => book.Isbn)
  • ToLookUp:把集合转换成ILookup<TKey,TElement>类型的集合,ILookup<TKey,TElement>集合与Dictionary<TKey,TElement>集合不同的是:Dictionary<TKey,TElement>中Key和Value值一一对应,而ILookup<TKey,TElement>集合中Key和Value值是一对多的对应关系。
  • SequenceEqual:用来对两个序列进行对比。如果所有元素的值相等,并且元素个数相等,并且元素的次序相等,那SequenceEqual操作符返回的是True,否则返回False。
  • First、FirstOrDefault:如果序列中包含一个或多个元素,这两个操作符返回序列中的第一个元素。如果序列不包含任何元素,则FirstOrDefault操作符返回null值(引用类型)或默认值(值类型),而First操作符则产生异常信息。
  • Last、LastOrDefault:如果序列中包含一个或多个元素,这两个操作符返回序列中的最后一个元素。如果序列不包含任何元素,则LastOrDefault操作符返回null值(引用类型)或默认值(值类型),而Last操作符则产生异常信息。
  • Single、SingleOrDefault:如果序列中有且只有一个元素,则这两个操作符返回该元素
    如果序列中没有任何元素,则Single会产生异常,而SingleOrDefault则会返回null值(引用类型)或默认值(值类型)
    如果序列中包含多个元素,则这两个操作符都会产生异常。
  • ElementAt、ElementAtOrDefault:这两个操作符是根据索引号从序列中返回指定的元素,如果未找到元素ElementAt()会产生异常,而ElementAtOrDefault()则会返回默认实例。
  • Any:如果序列中存在任一个满足条件的元素,就返回true
  • All:如果序列中所有元素都满足条件,就返回true
  • Contains:判断集合中是否包含指定的元素
  • Count:取得序列中满足条件的元素的个数
    • var count2 = SampleData.Books.Count(book => book.Price > 30)
  • LongCount:取得序列中满足条件的元素的个数(返回类型为int64类型)
  • Sum:序列中所有元素中某属性的总和
    • var sum = SampleData.Books.Sum(book=>book.Price);
  • Min:序列中所有元素中某属性的最小值
    • var min = SampleData.Books.Min(book => book.Price);
  • Max:序列中所有元素中某属性的最大值
    • var max = SampleData.Books.Select(book => book.Price).Max();
  • Average:序列中所有元素中某属性的平均值
    • var average = SampleData.Books.Select(book => book.Price).Average();
  • Aggregate:这个语法可以做一些复杂的聚合运算,例如累计求和,累计求乘积。它接受2个参数,一般第一个参数是称为累积数(默认情况下等于第一个值),而第二个代表了下一个值。第一次计算之后,计算的结果会替换掉第一个参数,继续参与下一次计算。
    •         static void Main(string[] args)
              {
      
                  var numbers = GetArray(5);
                //阶乘示例
                  var result = (from n in numbers
                               select n).Aggregate(
                                  (total, next) =>
                                  {
                                      return total * next;
                                  });
      
                  Console.WriteLine("5的阶乘为:{0}",result);//返回120,也就是1*2*3*4*5
      
              }
      
              static IEnumerable<int> GetArray(int max) {
                  List<int> result = new List<int>(max);
                  for (int i = 0; i < max; i++)
                  {
                      result.Add(i+1);
                  }
      
                  return result;
      
              }

由于精力有限,例子不够丰富,不过基本的语义解释清楚了,语法应该很好懂,有时间再把示例语句补上,本人不怎么会排版,排版很烂,会慢慢改进,欢迎指教任何问题,谢谢。

Linq to Object 的简单使用示例,布布扣,bubuko.com

时间: 2024-10-24 05:35:36

Linq to Object 的简单使用示例的相关文章

Linq to OBJECT延时标准查询操作符

1.Where 操作符用于限定输入集合中的元素,将符合条件的元素组织声称一个序列结果. 2.Select  操作符用于根据输入序列中的元素创建相应的输出序列中的元素,输出序列中的元素类型可以与输入序列中的元素类型相同,也可以不同.下面来看看Select方法的原型. 3.SelectMany 操作符用于根据输入序列中的每一个元素,在输出序列中创建相应的零个或者多个元素,与Select操作符不同,Select操作符会根据输入序列中的每一个元素创建一个对应的输出序列元素,而SelectMany操作符可

LINQ to Object

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Collections; 5 6 namespace Demo1 7 { 8 class Program 9 { 10 11 static void Main(string[] args) 12 { 13 Console.WriteLine("简单查询"); 14 string[] currentVideoGam

.NET面试题系列[13] - LINQ to Object

.NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Query(语言集成查询)的缩写,读音和单词link相同.不要读成“lin-Q”. LINQ to Object将查询语句转换为委托.LINQ to Entity将查询语句转换为表达式树,然后再转换为SQL. LINQ的好处:强类型,相比SQL语句它更面向对象,对于所有的数据库给出了统一的操作方式. LINQ的一些

Linq技术三:Linq to Object 和生成数据表的扩展方法

这篇来谈论一下Linq第三个方面的应用:Linq to Object,只要是继承了IEnumerable或IQueryable接口的Object都能使用Linq特性进行操作.在操作过程当中可能很多人都觉得不好调试不能实时地观察结果数据集,想把IQuery的Linq查询语句转换成数据表DataTable,要怎么实现转换呢?来看一下. 先来说一场景解释一下为什么需要用Linq来解决一些问题,能解决一些什么样的问题,相对于SQL,DataTable等一些传统操作方式有哪些优势? 场景:目前主要数据源有

Webservice简单调用示例

Webservice简单调用示例 webservice主要是一些站点为我们写好了的方法,供我们调用,当然我们也可以自己去编写自己的webservice,本文主要是通过一个小的实例,去如何调用webservice.下面先给出几个常用的webservice的调用地址. 快递查询接口 http://webservice.36wu.com/ExpressService.asmx ip查询接口 http://webservice.36wu.com/ipService.asmx 天气预报接口 http://

JS javascript面向对象的理解及简单的示例

javascript面向对象的理解及简单的示例 一. javascript面向对象概念: 为了说明 JavaScript 是一门彻底的面向对象的语言,首先有必要从面向对象的概念着手 , 探讨一下面向对象中的几个概念: 1.一切事物皆对象 2.对象具有封装和继承特性 3.对象与对象之间使用消息通信,各自存在信息隐藏 以这三点做为依据,C++ 是半面向对象半面向过程语言,因为,虽然他实现了类的封装.继承和多态,但存在非对象性质的全局函数和变量.Java.C# 是完全的面向对象语言,它们通过类的形式组

(第一篇) 一步一步带你了解linq to Object

要想学好linq to object 我们必须要先学习lambda 表达式,学习lambda 表达式呢我们必须了解匿名函数和匿名类,学习匿名函数,我们必须学会委托,这是本文的宗旨.下面开始第一步.在第一步开始之前,我们做点准备工作,建立一个学生类和一个班级类,类结构如下 public class Student { public int Id { get; set; } public int ClassId { get; set; } public string Name { get; set;

LINQ to Object——延时执行的Enumerable类方法

LINQ to Object是针对实现了IEnumerable<T>的对象的LINQ.而在System.Linq.Enumerable类中,总共定义了40来个查询运算符----全部用扩展方法来实现,他们被称为标准查询运算符.每个查询运算符的执行行为不同,大致分为立即执行和延时执行.延时执行,顾名思义就是不是立即执行,即不是在查询语句定义的时候执行,而是在处理结果集(如遍历)的时候执行. 常用的延时执行的Enumerable类方法成员,具体如下: 1.Take用于从一个序列的开头返回指定数量的元

LINQ to Object初体验(使用对象取代二维数组作数据筛选)

VS2008里面有个神奇的东西,称之为LINQ,可以透过相同的语法方式来处理各式各样的数据(SQL,XML,Object,...),小喵此次初体验感受一下这个东西,真的很好用,初体验来做个简单的测试,请看小喵娓娓道来 VS2008里面有个神奇的东西,称之为LINQ,可以透过相同的语法方式来处理各式各样的数据(SQL,XML,Object,...),小喵此次初体验感受一下这个东西,真的很好用,初体验来做个简单的测试,请看小喵娓娓道来 先来看一张LINQ的架构图(数据来源:曹祖圣老师在TechEd2