新Orcas语言特性-查询句法(2)
来源:asp之家 发布时间:2010-07-16 12:58:00
查询句法 - 理解where和orderby子句:
在一个查询句法表达式开头的"from" 子句和结尾的"select"子句之间,你可以使用最常见的LINQ查询运算符来过滤和转换你在查询的数据。两个最常用的子句是"where"和"orderby"。这两个子句处理对结果集的过滤和排序。
譬如,要从Northwind数据库里返回按字母降序排列的分类名称列表,过滤条件是只包括那些含有5个以上产品的分类,我们可以编写下面这样的查询句法来用LINQ到SQL对我们的数据库做查询:
在上面的表达式里,我们加了 "where c.Products.Count > 5" 子句来表示我们只要那些含有5个以上产品的分类。这利用了数据库中产品和分类间的LINQ到SQL的ORM映射的关联。在上面的表达式中,我也加了"order by c.CategoryName descending"子句来表示我要将结果集按名称降序排列。
LINQ到SQL然后就会在使用这个表达式查询数据库时,生成下列SQL:
Select [t0].[CategoryName] FROM [dbo].[Categories] AS [t0]
Where ((
Select COUNT(*)
FROM [dbo].[Products] AS [t1]
Where [t1].[CategoryID] = [t0].[CategoryID]
)) > 5
ORDER BY [t0].[CategoryName] DESC
注意,LINQ到SQL很聪明,只返回了我们所需的单个字段(分类名称), 而且它是在数据库层做了所有的过滤和排序,使得该查询效率非常高。
查询句法 - 用投影(Projection)来转换数据
先前我指出的一个要点是,"select" 子句表示了你要返回的数据,以及这个数据的构形是什么。
譬如,假如你有个象下面这样的"select p" 子句,这里p的类型是Person,然后,它就会返回一串Person对象:
LINQ和查询句法提供的一个非常强大的功能是允许你定义跟被查询的数据分开的新的类型,然后用新的类型来控制查询返回的数据的形状和结构。
譬如,假设我们定义了一个新的AlternatePerson类,内含一个FullName属性,而不是我们原先的Person类内的分开的FirstName和LastName属性:
然后我就可以使用下面的LINQ查询句法来查询我原先的List<Person>集合,用下面的查询句法将结果转换成一串AlternatePerson对象:
注意看,我们是如何在上面的表达式里的"select"子句里,使用我的语言系列的第一个贴子里讨论过的新的对象初始化器句法来创建新的AlternatePerson实例,同时设置它的属性的。也注意我是如何连接我们原先Person类的FirstName和LastName属性,然后将其赋值给FullName属性的。
对数据库使用查询句法投影
这个投影特性在操作从象数据库这样一个远程数据提供器那里取回的数据时,会变得难以置信地有用,因为它提供给我们一个优雅的方式,来表示我们的ORM应该从数据库实际取回哪些数据字段。
譬如,假设我用了LINQ到SQL的ORM提供器对Northwind数据库建模,生成下面这些类:
通过编写下面这个LINQ查询,我告诉LINQ到SQL我要返回一串Product对象:
填充Product类所需的所有字段都将作为上面查询的一部分从数据库中返回,由LINQ到SQL orM执行的raw SQL看上去象下面这样:
Select [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID],
[t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock],
[t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
Where [t0].[UnitPrice] > 99
在一些场景下,我不需要也不用所有这些字段,我可以定义一个下面这样的新的MyProduct类,只拥有Product类具有的部分属性,以及一个Product类并不具有的额外属性,TotalRevenue (注: 对那些不熟悉C#的,Decimal?句法表示我们的UnitPrice属性是个nullable值):
然后我就可以使用下面这个查询,使用查询句法的投影功能来构造我要从数据库返回的数据的形状:
这表明,不是返回一串Product对象,我要MyProduct对象,我只要其中三个属性被赋值,LINQ到SQL就会很聪明地调整要执行的raw SQL语句,从数据库只返回那三个需要的产品字段:
Select [t0].[ProductID], [t0].[ProductName], [t0].[UnitPrice]
FROM [dbo].[Products] AS [t0]
Where [t0].[UnitPrice] > 99
为炫耀起见,我也可以填充MyProduct类的第四个属性,即TotalRevenue属性。我要这个值等于我们产品目前的销售额的总量。这个值在Northwind数据库中并没有作为一个预先算好的字段而存在。而是,你需要在Products表和Order Details表间做一个关联,然后计算出一个给定产品对应的所有的Order Detail 行的总量。
非常酷的是,我可以在Product类的OrderDetails关联上使用LINQ的 Sum 这个扩展方法,编写一个作为我的查询句法投影一部分的乘法Lambda表达式,来计算这个值:
LINQ到SQL就会非常聪明地使用下面这个SQL在SQL数据库里做运算:
Select [t0].[ProductID], [t0].[ProductName], [t0].[UnitPrice], (
Select SUM([t2].[value])
FROM (
Select [t1].[UnitPrice] * (CONVERT(Decimal(29,4),[t1].[Quantity])) AS [value], [t1].[ProductID]
FROM [dbo].[Order Details] AS [t1]
) AS [t2]
Where [t2].[ProductID] = [t0].[ProductID]
) AS [value]
FROM [dbo].[Products] AS [t0]
Where [t0].[UnitPrice] > 99


猜你喜欢
- ant-design-vue自定义使用阿里iconfont图标\第一步:从iconfont获取项目js链接第二步 在需要引用iconfont
- Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。换句话说,我们可以把这个类型的对象当作
- argparse 是 python 的一个命令行解析包,可根据需要编写高可读性的程序。网上的许多教程较为冗长和散漫,没有达到精练好掌握的目的
- 本文实例讲述了Python基于PyGraphics包实现图片截取功能的方法。分享给大家供大家参考,具体如下:先安安装PyGraphics包
- 详解Python import方法引入模块的实例在Python用import或者from…import或者from…import…as…来导
- 本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式。分享给大家供大家参考,具体如下:表单介绍表单是HTML页面中负责数据采集功
- 这几天做了一个专题,放到服务器后发现从首页链接到专题页面正常,但是从专题页面跳转到首页就会出现乱码。很是蹊跷,专题页面和首页没有共同的文件,
- 在处理数据的时候,很多时候会遇到批量替换的情况,如果一个一个去修改效率过低,也容易出错。replace()是很好的方法。源数据1、替换全部或
- 一、前言数据库的数据量达到一定程度之后,为避免带来系统性能上的瓶颈。需要进行数据的处理,采用的手段是分区、分片、分库、分表。二、分片(类似分
- 函数的增益值torch.nn.init.calculate_gain(nonlinearity, param=None)提供了对非线性函数增
- 本文实例讲述了python打开文件并获取文件相关属性的方法。分享给大家供大家参考。具体分析如下:下面的代码通过open函数打开文件,并输出文
- python中,遍历dict的方法有四种。但这四种遍历的性能如何呢?我做了如下的测试l = [(x,x) for x in xrange(1
- 今天说一些golang的基础知识,还有你们学习会遇到的问题,先讲解hello wordpackage mainimport "fm
- 发现问题一个作业报错,报错信息如下,从错误信息根本看不出为什么出错,手工运行作业又成功了。一时不清楚什么原因导致作业出错。MessageEx
- Zabbix的简单安装配置说明1、在已有的LAMP或者LNMP的基础上安装zabbix,安装一些依赖包:yum -y install mys
- vue异步更新源码中会有涉及事件循环、宏任务、微任务的概念,所以先了解一下这几个概念。一、事件循环、宏任务、微任务1.事件循环Event L
- 01 示例函数1.1 代码及结果import matplotlib.pyplot as pltimport matplotlib.
- 我自己测试一下,很多字符变成了 ‘?'。数据库连接已经是使用了 utf8 字符集:define("MYSQL_ENCODE
- python2和python3对于字符串的处理有很大的区别熟悉了python2的写法用python3时真的会遇到很多问题啊……区别pytho
- 视图函数中加上认证功能,流程见下图import hashlibimport timedef get_random(name):