Linq to Object 的简单使用示例
语言集成查询 (LINQ) 是 Visual Studio 2008 中引入的一组功能,可为 C# 和 Visual Basic 语言语法提供强大的查询功能。 LINQ 引入了标准易学的数据查询和更新模式,可以扩展该方法来支持任何类型的数据存储。 Visual Studio 包括 LINQ 提供程序集,后者支持将 LINQ 与 .NET Framework 集合、SQL Server 数据库、ADO.NET 数据集和 XML 文档结合使用。
LINQ特有的编程结构:
- 隐式类型本地变量:C#的var关键字允许定义不显式指定实际数据类型的本地变量。不过由于编译器将根据初始值推断其数据类型,所有该变量仍然是强类型的。
- 对象和集合初始化语法:它允许我们在创建类或结构变量的同时设置其属性。
- Lambda表达式:C#Lambda操作符(=>)可以用来构建Lambda表达式,并且在调用以强类型的委托作为参数的方法时,也十分有用。
- 扩展方法:C#扩展方法不使用子类就能够像已知类中添加新的功能。同样,它还可以向不能有子类的密封类和结构中添加新的功能。在编写扩展方法时,第一个参数必须使用this限定符,用来表示被扩展的类型。扩展方法只能定义在静态类中,并且必须使用static关键字声明为静态方法。
- 匿名类型:该特性可以快速建立数据的“结构”,编译器将根据名称/值对的结合在编译时生成新的类。该类型是基于值的语义构建的,因此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[],
Authors=new[]{Authors[], Authors[]},
PageCount=,
Price=25.55M,
PublicationDate=new DateTime(, , ),
Isbn="0-000-77777-2",
Subject=Subjects[]
},
new Book {
Title="LINQ rules",
Publisher=Publishers[],
Authors=new[]{Authors[]},
PageCount=,
Price=12M,
PublicationDate=new DateTime(, , ),
Isbn="0-111-77777-2",
Subject=Subjects[]
},
new Book {
Title="C# on Rails",
Publisher=Publishers[],
Authors=new[]{Authors[]},
PageCount=,
Price=35.5M,
PublicationDate=new DateTime(, , ),
Isbn="0-222-77777-2",
Subject=Subjects[]
},
new Book {
Title="All your base are belong to us",
Publisher=Publishers[],
Authors=new[]{Authors[]},
PageCount=,
Price=35.5M,
PublicationDate=new DateTime(, , ),
Isbn="0-333-77777-2",
Subject=Subjects[]
},
new Book {
Title="Bonjour mon Amour",
Publisher=Publishers[],
Authors=new[]{Authors[], Authors[]},
PageCount=,
Price=29M,
PublicationDate=new DateTime(, , ),
Isbn="2-444-77777-2",
Subject=Subjects[]
}
};
}
}
一、概述
LINQ to OBJECT是用于操作内存对象的LINQ编程接口,包含了大量的查询操作符,针对内存中的集合对象进行操作。LINQ TO OBJECT的大部分操作是针对序列的。标准查询操作符本质是一些扩展方法。
二、延时标准查询操作符
I、延时标准查询操作符是指具备延时查询特性的标准查询操作符,这些操作符构成了LINQ TO OBJECT编程接口的最主要内容。
主要包括:(以下示例中,一般第一个方法为Linq扩展方法,第二个方法为查询表达式语法)
- Where:根据谓词对源序列的内容进行筛选,类似于SQL中的where子句。
var books = SampleData.Books.Where(b => b.Price > ); var books1 = from book in SampleData.Books
where book.Price >
select book;
//多条件直接用“&&”或者“||”来组合
var book2 = SampleData.Books.Where(b => b.Price > && b.PageCount > );
- 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);
- var bookTitles = SampleData.Books.Select(b => b.Title);
- 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);
- var bookTitles = SampleData.Books.Select(b => b.Title);
- Intersect:Intersect操作符是取两个具有相同结构的集合的交集部份。
- var bookTitles = SampleData.Books.Select(b => b.Title);
var authorNames = SampleData.Authors.Select(a => a.FirstName);
var temp = bookTitles.Intersect(authorNames);
- var bookTitles = SampleData.Books.Select(b => b.Title);
- 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);
- var bookTitles = SampleData.Books.Select(b => b.Title);
- Cast:
ArrayList booksList = new ArrayList(SampleData.Books); var query = from book in booksList.Cast<Book>()
where book.PageCount >
select new
{
book.Title,
book.PageCount
}; var query2 = from Book book in booksList
where book.PageCount >
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();
//阶乘示例
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 = ; i < max; i++)
{
result.Add(i+);
} return result; }
由于精力有限,例子不够丰富,不过基本的语义解释清楚了,语法应该很好懂,有时间再把示例语句补上,本人不怎么会排版,排版很烂,会慢慢改进,欢迎指教任何问题,谢谢。
Linq to Object 的简单使用示例的更多相关文章
- Linq to OBJECT延时标准查询操作符
1.Where 操作符用于限定输入集合中的元素,将符合条件的元素组织声称一个序列结果.2.Select 操作符用于根据输入序列中的元素创建相应的输出序列中的元素,输出序列中的元素类型可以与输入序列中 ...
- LINQ&EF任我行(二)--LinQ to Object
(原创:灰灰虫的家http://hi.baidu.com/grayworm)LinQ to Objects是LinQ家庭的核心,其它的LinQ也使用了与LinQ to Objects相同的查询句法.最 ...
- Linq to Object 延迟标准查询操作符
1.Where 操作符用于限定输入集合中的元素,将符合条件的元素组织声称一个序列结果.2.Select 操作符用于根据输入序列中的元素创建相应的输出序列中的元素,输出序列中的元素类型可以与输入序列中 ...
- .NET面试题系列[13] - LINQ to Object
.NET面试题系列目录 名言警句 "C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard LINQ是Language Integrated Que ...
- LINQ系列:Linq to Object生成操作符
生成操作符从现有序列值中创建新的序列. 1. Empty Empty操作符返回一个指定类型的空集. 1>. 原型定义 public static IEnumerable<TResult& ...
- LINQ系列:Linq to Object转换操作符
转换是指将输入对象的类型转变为序列的动作. 1. AsEnumerable AsEnumerable操作符将查询的输入以IEnumberable(T)类型返回. 2. Cast Cast操作符将IEn ...
- LINQ系列:Linq to Object量词操作符
量词操作符返回一个Boolean值,指示序列中是否存在部分或全部元素符号指定条件.LINQ中量词操作符包括:All.Any和Contains. 1. All All操作符判定在集合中是否所有的值都满足 ...
- LinQ To Object 基本用法
http://www.cnblogs.com/terryzh/archive/2012/11/10/2763538.html LinQ To Object 基本用法 inq的基本语法:var resu ...
- hadoop环境安装及简单Map-Reduce示例
说明:这篇博客来自我的csdn博客,http://blog.csdn.net/lxxgreat/article/details/7753511 一.参考书:<hadoop权威指南--第二版(中文 ...
随机推荐
- Process ProcessThread Thread
Process ProcessThread: Process and ProcessThread objects have a ProcessorAffinity property of IntPtr ...
- PS切图导出代码后出现的图片布局散乱的解决方法——table布局
前言: 一般来说,大部分美工PS切图后导出的都是使用PS默认的table布局的页面,出现最多的异常是上传代码,替换图片后,发现图片布局散乱,完全不是想要的效果.轻微的是浏览器不兼容,只有部分浏览器可以 ...
- iOS 各种方法
tableViewCell分割线左对齐: - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)c ...
- [leetcode]199. Binary Tree Right Side View二叉树右视图
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nod ...
- linux 下 php 安装 ZeroMQ 扩展
一.下载安装源码包 ZeroMQ源码包下载地址: http://zeromq.org/area:download 如:zeromq-4.1.4.tar.gz php的zmq扩展源码包 https: ...
- 【原创】有关Silverlight中自动生成的类中 没有WCF层edmx模型新加入的对象 原因分析。
前端页面层: 编译老是不通过,报如下如所示错误: -- 然后下意识的查了下 生成的cs文件,没有搜到根据edmx 生成的 对应的类. 结果整理: 1.尽管在 edmx 模 ...
- linux下给php安装memcached及memcache扩展(转)
http://kimi.it/257.html (另外的方法)linux安装memcached及memcache扩展一.安装libevent函数库下载地址:http://libevent.org默认被 ...
- 移动端UI设计规范模板参考以及设计规范的好处
2018也快要过完了(-_-),我们的移动端的UI设计规范也层出不穷.很多APP设计师也要在年底给公司或者是团队做一个总结.那么一个像样的APP ui设计规范也是很有必要的作品回顾. 在创业公司做着一 ...
- 1、wei-d-s嵌入式与PC区别,LED等的点亮以及调用C函数
tiny6410之点亮Led灯: .global _start _start: ldr r0,0x70000000 //目的是把外设基地址告诉cpu orr r0,r0,#0x13 mcr p15,0 ...
- Centos记录所有用户登录和操作的详细日志
1.起因 最近Linux服务器上一些文件呗篡改,想追查已经查不到记录了,所以得想个办法记录下所有用户的操作记录. 一般大家通常会采用history来记录,但是history有个缺陷就是默认是1000行 ...