Linq 学习笔记(二)

Linq 学习笔记(二)

下面就来介绍一些查询的示例:

1。Linq查询

var racers = from r in Formula1.GetChampions()
where r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria") select r;
foreach (var r in racers)
{
Responose.Write("{0:A}", r);
}

使用扩展方法的查询

并不是所有的查询都可以用LINQ查询完成。也不是所有的扩展方法都映射到LINQ查询子句上。高级查询需要使用扩展方法。为了更好地理解带扩展方法的复杂查询,最好看看简单的查询是如何映射的。使用扩展方法Where()和Select(),会生成与前面LINQ 查询非常类似的结果:

var racers = Formula1.GetChampions().Where(r => r.Wins > 15 && (r.Country == "Brazil" || r.Country == "Austria")).Select(r = > r);

2。用索引来过滤

不能使用LINQ 查询的一个例子是Where()方法的重载。在Where()方法的重载中,可以传送第二个参数——索引。索引是过滤器返回的每个结果的计数器。可以在表达式中使用这个索引,执行基于索引的计算。下面的代码由Where()扩展方法调用,它使用索引返回姓氏以A开头、索引为偶数的赛手:

var racers = Formula1.GetChampions().Where((r, index) => r.LastName.StartsWith("A") &&

index % 2 != 0);
foreach (var r in racers)
{
Responose.Write("{0:A}", r);

}

3。类型过滤

为了进行基于类型的过滤,可以使用OfType()扩展方法。这里数组数据包含string和int对象。使用OfType()扩展方法,把string类传送给泛型参数,就从集合中返回字符串。

object[] data = { "one", 2, 3, "four", "five",6 };
var query = data.OfType<string>();
foreach (var s in query)
{
Console.WriteLine(s);
}

4。复合的from子句

var ferrariDrivers = from r in Formula1.GetChampions() from c in r.Cars where c == "Ferrari"
orderby r.LastName select r.FirstName + " " + r.LastName; 

C#编译器把复合的from 子句和LINQ 查询转换为SelectMany()扩展方法。SelectMany()可用于迭代序列的序列。示例中SelectMany()方法的重载版本如下所示:

public static IEnumerable<TResult> SelectMany<TSource,TCollection,TResult>(this IEnumerable<TSource> source,Func<TSource,IEnumerable<TCollection>> collectionSelector,Func<TSource,TCollection,TResult>resultSelector);

第一个参数是隐式参数,从GetChampions()方法中接收Racer对象序列。第二个参数是collectionSelector委托,它定义了内部序列。在λ表达式r=>r.Cars中,应返回赛车集合。第三个参数是一个委托,现在为每个赛车调用该委托,接收Racer和Car对象。λ表达式创建了一个匿名类型,它带Racer和Car属性。这个SelectMany()方法的结果是摊平了赛手和赛车的层次结构,为每辆赛车返回匿名类型的一个新对象集合。

这个新集合传送给Where()方法,过滤出驾驶Ferrari 的赛手。最后,调用OrderBy()和Select()方法:
var ferrariDrivers = Formula1.GetChampions().SelectMany(r => r.Cars,
(r, c) => new { Racer = r, Car = c }).Where(r => r.Car == "Ferrari").OrderBy(r =>r.Racer.LastName).Select(r => r.Racer.FirstName + " " +r.Racer.LastName);
把SelectMany()泛型方法解析为这里使用的类型,所解析的类型如下所示。在这个例子中,数据源是
Racer类型,所过滤的集合是一个string数组,当然所返回的匿名类型的名称是未知的,这里显示为TResult:
public static IEnumerable<TResult> SelectMany<Racer, string, TResult>(
this IEnumerable<Racer> source,Func<Racer,IEnumerable<string>> collectionSelector,
Func<Racer,string,TResult> resultSelector);
查询仅从LINQ 查询转换为扩展方法,所以结果与前面的相同。

5。排序

var racers = from r in Formula1.GetChampions() where r.Country == "Brazil" orderby r.Wins descending select r;

orderby子句解析为OrderBy()方法,orderby descending子句解析为OrderBy Descending()方法:

var racers = Formula1.GetChampions().Where(r => r.Country == "Brazil").OrderByDescending(r => r.Wins).Select(r => r);

OrderBy()和OrderByDescending()方法返回IOrderEnumerable<TSource>。这个接口派生于接口IEnumerable<TSource>,但包含一个额外的方法CreateOrderedEnumerable-<TSource>()。这个方法用于进一步给序列排序。如果根据关键字选择器来排序,两项的顺序相同,就可以使用ThenBy()和ThenByDescending()方法继续排序。这两个方法需要IOrderEnumerable<TSource>才能工作,但也返回这个接口。所以,可以添加任意多个ThenBy()和ThenByDescending()方法,对集合排序。

使用LINQ 查询时,只需把所有用于排序的不同关键字(用逗号分隔开)添加到orderby 子句中例如

var racers = (from r in Formula1.GetChampions() orderby r.Country, r.LastName, r.FirstName select r).Take(10);

6。分组

var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 2 select new { Country = g.Key, Count = g.Count() };
foreach (var item in countries)
{
Response.Write("{0, -10} {1}",item.Country, item.Count);
}

扩展方法的分组表示:

var countries = Formula1.GetChampions().GroupBy(r => r.Country).OrderByDescending(g => g.Count()).
ThenBy(g => g.Key).Where(g => g.Count() >= 2).Select(g => new { Country = g.Key,Count = g.Count()});

7。对嵌套的对象分组

如果分组的对象应包含嵌套的对象,就可以改变select 子句创建的匿名类型。

var countries = from r in Formula1.GetChampions() group r by r.Country into g orderby g.Count() descending, g.Key where g.Count() >= 2 select new
{
Country = g.Key, Count = g.Count(),

Racers = from r1 in g orderby r1.LastName select r1.FirstName + " " + r1.LastName
};
foreach (var item in countries)
{
Response.Write("{0, -10} {1}", item.Country, item.Count);
foreach (var name in item.Racers)
{
Response.Write("{0}; ", name);
}
Response.Write("<br/>");
}

8。连接

使用join 子句可以根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。

var racers = from r in Formula1.GetChampions() from y in r.Years where y > 2003 select new
{
Year = y,
Name = r.FirstName + " " + r.LastName
};

var teams = from t in Formula1.GetContructorChampions() from y in t.Years where y > 2003

select new { Year = y, Name = t.Name };

有了这两个查询,再通过子句join t in teams on r.Year equals t.Year就可以得到结果集了。

var racersAndTeams = from r in racers join t in teams on r.Year equals t.Year select new
{
Year = r.Year,
Racer = r.Name,
Team = t.Name
};
Response.Write("Year Champion " + "Constructor Title");
foreach (var item in racersAndTeams)
{
Response.Write("{0}: {1,-20} {2}",item.Year, item.Racer, item.Team);
}

9。设置操作

扩展方法Distinct()、Union()、Intersect()和Except()都是设置操作。

var ferrariDrivers = from r in Formula1.GetChampions() from c in r.Cars where c == "Ferrari"
orderby r.LastName select r;
现在建立另一个相同的查询,但where 子句的参数不同,以获得所有驾驶McLaren 的冠军。最好不要再次编写相同的查询。而可以创建一个方法,给它传送参数car:
private static IEnumerable<Racer> GetRacersByCar(string car)
{
return from r in Formula1.GetChampions() from c in r.Cars where c == car orderby r.LastName select r;
}
但是,因为该方法不需要在其他地方使用,所以应定义一个委托类型的变量来保存LINQ 查询。变量racerByCar 必须是一个委托类型,它需要一个字符串参数,返回IEnumerable <Racer>,类似于前面实现的方法。为此,定义了几个泛型委托Func<>,所以不需要声明自己的委托。把一个λ表达式赋予变量racerByCar。λ表达式的左边定义了一个car 变量,其类型是Func 委托的第一个泛型参数(字符串)。右边定义了LINQ 查询,它使用该参数和where 子句:
Func<string, IEnumerable<Racer>> racersByCar = Car => from r in Formula1.GetChampions() from c in r.Cars where c == car orderby r.LastName select r;
现在可以使用Intersect()扩展方法,获得驾驶Ferrari 和McLaren 的所有冠军:
Response.Write("World champion with " + "Ferrari and McLaren");
foreach (var racer in racersByCar("Ferrari").
Intersect(racersByCar("McLaren")))
{
Response.Write(racer);
}

10。分区

扩展方法Take()和Skip()等的分区操作可用于分页,例如显示5×5 个赛手。在下面的LINQ 查询中,扩展方法Take()和Skip()添加到查询的最后。Skip()方法先忽略根据页面的大小和实际的页数计算出的项数,再使用方法Take()根据页面的大小提取一定数量的项:
int pageSize = 5;
int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count()/(double)pageSize);

for (int page = 0; page < numberPages; page++)
{
Response.Write("Page {0}", page);
var racers = (from r in Formula1.GetChampions() orderby r.LastName select r.FirstName + " " + r.LastName).Skip(page * pageSize).Take(pageSize);
foreach (var name in racers)
{
Response.Write(name);
}
Response.Write();
}

11。合计操作符

合计操作符如Count()、Sum()、Min()、Max()、Average()和Aggregate(),不返回一个序列,而返
回一个值。

var query = from r in Formula1.GetChampions() where r.Years.Count() > 3 orderby r.Years.Count() descending select new
{
Name = r.FirstName + " " +r.LastName,
TimesChampion = r.Years.Count()
};
foreach (var r in query)
{
Response.Write("{0} {1}", r.Name, r.TimesChampion);
}

Sum()方法汇总序列中的所有数字,返回这些数字的和。下面的Sum()用于计算一个国家赢得比赛的
总次数。首先根据国家对赛手分组,再在新创建的匿名类型中,给Wins 属性赋予某个国家赢得比赛的总
次数。

var countries = (from c in from r in Formula1.GetChampions() group r by r.Country into c

select new
{
Country = c.Key,
Wins = (from r1 in c select r1.Wins).Sum()
}
orderby c.Wins descending, c.Country select c).Take(5);
foreach (var country in countries)
{
Response.Write("{0} {1}",country.Country, country.Wins);
}

方法Min()、Max()、Average()和Aggregate()的使用方式与Count()和Sum()相同。Min()返回集合
中的最小值,Max()返回集合中的最大值,Average()计算集合中的平均值。对于Aggregate()方法,可
以传送一个λ表达式,对所有的值进行汇总。

12。转换

查询可以推迟到访问数据项时再执行。在迭代中使用查询,查询会执行。而使用转换操作符会立即执行查询,把结果放在数组、列表或字典中。在下面的例子中,调用ToList()扩展方法,立即执行查询,把结果放在List<T>中:

List < Racer > racers = (from r in Formula1.GetChampions()
where r.Starts > 150 orderby r.Starts descending select r).ToList();
foreach (var racer in racers)
{
Response.Write("{0} {0:S}", racer);
}

把返回的对象放在列表中并没有这么简单。例如,对于集合中从赛车到赛手的快速访问,可以使用新类Lookup<TKey, TElement>。

提示:
Dictionary<TKey, TValue>只支持一个键对应一个值。在System.Linq 命名空间的类Lookup<TKey,
TElement>中,一个键可以对应多个值。这些类详见第10 章。
使用复合的from 查询,可以摊平赛手和赛车序列,创建带有Car 和Racer 属性的匿名类型。在返回的Lookup 对象中,键的类型应是表示汽车的string,值的类型应是Racer。为了进行这个选择,可以给ToLookup()方法的一个重载版本传送一个键和一个元素选择器。键选择器表示Car 属性,元素选择器表示Racer 属性。

ILookup<string, Racer> racers = (from r in Formula1.GetChampions() from c in r.Cars select new
{ Car = c, Racer = r }).ToLookup(cr = > cr.Car, cr = > cr.Racer);
if (racers.Contains("Williams"))
{
foreach (var williamsRacer in racers["Williams"])
{
Response.Write(williamsRacer);
}
}

如果需要在未类型化的集合上使用LINQ查询,例如ArrayList,就可以使用Cast()方法。在下面的例子中,基于Object 类型的ArrayList 集合用Racer 对象填充。为了定义强类型化的查询,可以使用Cast()方法。
System.Collections.ArrayList list = new System.Collections.ArrayList(Formula1.GetChampions() as
System.Collections.ICollection);
var query = from r in list.Cast <Racer>() where r.Country == "USA" orderby r.Wins descending select r;
foreach (var racer in query)
{
Response.Write("{0:A}", racer);
}

13。生成操作符

生成操作符Range()、Empty()和Repear()不是扩展方法,而是返回序列的正常静态方法。在LINQto Objects 中,这些方法可用于Enumerable 类。有时需要填充一个范围的数字,此时就应使用Range()方法。这个方法把第一个参数作为起始值,把第二个参数作为要填充的项数。
var values = Enumerable.Range(1, 20);
foreach (var item in values)
{
Response.Write("{0} ", item);
}
Range()方法不返回填充了所定义值的集合,这个方法与其他方法一样,也推迟执行查询,返回一个RangeEnumerator,其中只有一个yield return 语句,来递增值。可以把该结果与其他扩展方法合并起来,获得另一个结果,例如使用Select()扩展方法:
var values = Enumerable.Range(1, 20).Select(n = > n * 3);
Empty()方法返回一个不返回值的迭代器,它可以用于参数需要一个集合,且可以给参数传送空集
合的情形。Repeat()方法返回一个迭代器,该迭代器把同一个值重复特定的次数。

 

 

ASP.NET开发技术交流群: 67511751(人员招募中...)

posted on 2011-08-31 16:03 Juvy 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/Juvy/archive/2011/08/31/2160847.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434888.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习在水文地质方面的文章--文献阅读

第一篇 Ensemble machine learning paradigms in hydrology: A review - ScienceDirecthttps://www.sciencedirect.com/science/article/pii/S0022169421003139?via%3Dihub第二篇 Stream water quality prediction using boosted regression tree and random forest models …

查询能力(SIP OPTIONS)

SIP方法OPTIONS允许一个UA来查询另外一个UA或者proxy服务器的能力。这个提供客户端一个手段来查询服务端支持的方法&#xff0c;内容类型&#xff0c;扩展&#xff0c;codecs等等。比如&#xff0c;在客户端试图在INVITE请求头中增加一个请求字段选项的时候&#xff0c;它并不知…

单体预聚合的目的是什么_高分子化学实验指导书-修改-2012

高分子化学实验指导书任课教师姓名&#xff1a;王小慧王小英所用教材&#xff1a;《高分子化学实验》何卫东主编中国科学技术大学出版社选读参考书&#xff1a;《高分子化学实验》梁晖卢江主编化学工业出版社一、教学形式1、课前&#xff0c;学生通过阅读参考书和《高分子化学实…

MemDC,GDI绘制注意点

最近绘制老犯同样的错误&#xff0c;记录下: 1.MemDC中的MemBmp大小一定要设定好&#xff0c;经常设小了&#xff0c;后面的绘不出来&#xff0c;同时最后dc.bitblt时&#xff0c;大小一定要和MemBmp 一致&#xff0c;同样经常是MemBmp必变了&#xff0c;bitblt的rcDest没变&am…

基于集成学习的不平衡数据集分类问题研究--文献阅读

参考文献 基于集成学习的不平衡数据集分类问题研究 - 中国知网https://kns.cnki.net/kcms/detail/detail.aspx?dbcodeCMFD&dbnameCMFD202201&filename1021697818.nh&uniplatformNZKPT&vK9J_5NETTyZXPhDr5D6KwISCv2zm0skRm7rEZ0KmYS0Yv_zs562Re8oiwR5h_ylK 文…

SIP注册

注册服务为特定地区的位置服务创建绑定关系&#xff0c;这个绑定关系是用来建立包含一个或者多个联系地址的address-of-recordURI。因而&#xff0c;当那个地区的proxy接收到一个请求&#xff0c;这个请求的Request-URI和address-of-record的记录匹配&#xff0c;那么这个proxy…

profile 安卓work_androidWorkProfileGeneralDeviceConfiguration 资源类型

androidWorkProfileGeneralDeviceConfiguration 资源类型androidWorkProfileGeneralDeviceConfiguration resource type2020/9/22本文内容命名空间&#xff1a;microsoft.graphNamespace: microsoft.graph注意&#xff1a; 适用于 Intune 的 Microsoft Graph API 需要适用于租户…

[读书笔记]TCP/IP详解V1读书笔记-1

TCP数据单元&#xff1a;tcp segment UDP数据单元&#xff1a;udp datagram IP数据单元&#xff1a;IP datagram 链路层单元&#xff1a;frame --------------------------------------- 应用层&#xff1a; SMTP&#xff1a;简单邮件传输协议 FTP&#xff1a;文件传输协议 DNS…

pandas划分数据

1.根据列位置划分 execldata pd.read_excel(filepath) # 获取列数 bandscount execldata.shape[1] #去除最后一列数据类别 bandscount bandscount - 1 classifypointdata execldata[:, 0:bandscount] classifypointlabel execldata[:, -1] 2.根据字段名称进行划分 exec…

SIP协议(基础技术知识)

SIP协议&#xff08;基础技术知识&#xff09; SIP&#xff08;Session InitiationProtocol&#xff09;协议是Internet多媒体通信和控制协议体系的一部分&#xff0c;该协议族包括会话描述协议(SDP)、会话发布协议(SAP)和会话启动协议(SIP)。会话描述协议用于描述会话发布、会…

python 程序停止打印日志_停止 Spring Boot 服务的几种优雅姿势

在使用 Spring Boot 的时候&#xff0c;都要涉及到服务的停止和启动&#xff0c;当我们停止服务的时候&#xff0c;很多时候大家都是 kill -9 直接把程序进程杀掉&#xff0c;这样程序不会执行优雅的关闭。而且一些没有执行完的程序就会直接退出。我们很多时候都需要安全的将服…

Office - 安装程序找不到office.zh-cn\*.文件

Office - 安装程序找不到office.zh-cn\*.文件 在同时安装vs2008 和 office2007 有可能会遇到个问题&#xff08;如果现在安装office2007&#xff0c;在安装vs2008 不会出现问题&#xff0c; 反正会出现下面问题&#xff09;在安装office2007时总是提示“安装程序找不到 offi…

批量导出部分依赖图(PDP)

部分依赖图 (PDP) 和个体条件期望 (ICE) 图可用于可视化和分析目标响应1与一组感兴趣的输入特征之间的交互。 部分依赖图 (PDP) 显示了目标响应与一组感兴趣的输入特征之间的依赖关系&#xff0c;边缘化了所有其他输入特征&#xff08;“补充”特征&#xff09;的值。直观地说…

c#读蓝牙数据_CSharp--BlueTooth 实现蓝牙通讯的程序 C#开发 可以发送和接收数据 方便二次开发 - 下载 - 搜珍网...

蓝牙C#/BluetoothDemo/bin/Debug/BluetoothDemo.exe蓝牙C#/BluetoothDemo/bin/Debug/OpenNETCF.BluetoothEx.dll蓝牙C#/BluetoothDemo/BluetoothDemo.csproj蓝牙C#/BluetoothDemo/BluetoothDemo.csproj.user蓝牙C#/BluetoothDemo/frmMain.cs蓝牙C#/BluetoothDemo/frmMain.Desig…

基于SDP的提议/应答(offer/answer)模型简介

1、引入 在松耦合会议中&#xff0c;会话参数完全由会议创建者来确定&#xff0c;参与者能做的仅仅是根据这些会话参数来加入会议&#xff08;当然也可以选择不加入&#xff09;。这种情况下&#xff0c;主要要做的就是会话描述&#xff0c;在这里SDP本身就足够了。 但是在更为…

arcgis已知两点投影坐标求距离

问题&#xff1a; 已知中心点坐标&#xff0c;求个点与中心点坐标的距离 解决方法如下&#xff1a; 新建字段 在新建字段上右键字段计算器 利用字段计算器进行两点间距离计算 不懂问题请进群交流询问相关知识点

【原创】StreamInsight查询系列(十九)——查询模式之检测异常

上篇文章介绍了查询模式中如何发现趋势&#xff0c;这篇博文将介绍StreamInsight中如何检测异常。 测试数据准备 为了方便测试查询&#xff0c;我们首先准备一个静态的测试数据源&#xff1a;var now DateTime.Parse("09/12/2011 8:57:00 PM"); var input new[] {n…

tensorflow 旋转图片_使用TensorFlow对图像进行随机旋转的实现示例

https://www.jb51.net/article/178934.htm在使用深度学习对图像进行训练时&#xff0c;对图像进行随机旋转有助于提升模型泛化能力。然而之前在做旋转等预处理工作时&#xff0c;都是先对图像进行旋转后保存到本地&#xff0c;然后再输入模型进行训练&#xff0c;这样的过程会增…

SIP协议详解

SIP协议概念** 会话启动协议SIP&#xff08;Session Initiation Protocol&#xff09;是一个在IP网络上进行多媒体通信的应用层控制协议&#xff0c;它被用来创 建、修改、和终结一个或多个参加者参加的会话进程。 **SIP协议可用于发起会话&#xff0c;也可以用于邀请成员加入…

arcgis判断两个字段是否相等

def a(b,c):if(bc):return 1else:return 0 不懂问题请进群交流