出处:Linq To Sql (Part.3 – Querying our database)

术语表

Built-in:内置的
Clause:子句
Debugger:调试器
Object Relational Mapper:对象关系映射器
ORM(Object Relation Mapping):对象关系映射
Visualizer:查看器
plug-in:插件程序
Breakpoint:断点
Shape:构造
object initialization:对象初始化
deferred execution model:延迟执行模型
sequences:序列
Object Initializer:对象初始化器
Collection Initializers:集合初始化器

上个月,我开始发表一个介绍LINQ TO SQL的随笔系列。LINQ TO SQL 是一个内置于.Net框架3.5版本的 O/RM (对象关系映射)框架,它使你可以方便地使用.Net类对关系数据库进行建模。你可以使用 LINQ 表达式来对数据库进行查询、添加、编辑、删除。

下面是我这系列随笔的前两篇:

l         Part 1:LINQ TO SQL 介绍

l         Part 2:定义我们的数据模型类

在今天这篇随笔中,我将继续详细为大家介绍如何使用我们在第二篇随笔中创建的这个数据模型,演示如何使用Asp.Net项目来对数据进行查询。

使用LINQ TO SQL建模了的 Northwind 数据库

在这一系列随笔中的第二篇,我一步步讲解了如何使用内置于VS2008中的LINT TO SQL设计器创建一个LINQ TO SQL类模型。下面是我们为Northwind范例数据库创建的类模型。

获取 Products

一旦我们定义了上面的数据模型类,我们可以方便的从我们的数据库中进行查询和获取数据。LINQ TO SQL通过对使用LINQ TO SQL设计器创建的NorthwindDataContext类编写LINQ查询语句来完成。

举个例子,如果想要获取一系列的Products对象,我可以像下面这个编写代码:

在上面的语句中,我在LINQ查询语句中使用了一个“Where”子句以返回属于特定Category的Products。我使用CategoryId来进行筛选。

LINQ TO SQL的优点之一是在定义如何查询数据的时候具有很大的灵活性,而且我还可以利用我在建立LINQ TO SQL数据类时建立的关系对数据库进行更加丰富和常见的查询。举个例子,我可以将这个查询修改成根据Product的CategoryName来实行,而不是像上面那样根据CategoryId,就像下面这样。

注意上面,我是如何使用Product的“ Category”属性去筛选Products,这些Products都属于拥有特定CategoryName的Category。这个属性由LINQ TO SQL自动为我们创建,因为我们在为Category和Product类建模的时候它们之间在数据库中拥有一对多的关系。

为了举一个在查询中使用我们数据模型的相联关系的例子,我们可以使用下面的LINQ查询语法,以获得那些有5个或者更多订单的Products。

注意上面,我们是如何使用LINQ TO SQL为我们在Product类上创建的“OrderDetails”集合(这是因为我们在使用LINQ TO SQL设计器时会有一个一对多关系)。

在调试时显示LINQ TO SQL的实际查询代码

当你在对你的对象进行查询或更新的时候,LINQ TO SQL对象关系映射器会自动进行创建、执行合适的SQL代码的操作。

开发者对于这种新的ORM最关心或者最恐惧的一个之一问题是“实际执行的是什么SQL代码?”。当你在调试你的应用程序时,LINQ一个非常好的特性就是它可以非常容易地查看实际执行的究竟是什么SQL代码。

从Visual Studio 2008的Beta2版本以后,你可以使用新的插件程序LINQ TO SQL查看器容易的查看(以及测试)任何LINQ TO SQL查询表达式。简单的在LINQ TO SQL查询上设置一个断点,然后单击放大图标来开启调试器的表达式查看器。

通过这样,你会看到一个对话框,上面显示了LINQ TO SQL在执行获取Product对象操作时的实际SQL代码:

如果你在这个对话框上点击“Execute”按钮,将会使用调试器直接执行这段SQL代码,并且看到从数据库中返回的实际结果集。

很显然,这样将非常容易准确地知道LINQ TO SQL为你执行的是什么SQL语句。值得注意到是在你需要做些改动的时候,你可以有选择的覆盖这个LINQ TO SQL所执行的SQL语句 – 尽管在98%的情况下,我想你会发现LINQ TO SQL所将执行的SQL代码是非常、非常好的。

绑定LINQ TO SQL查询到Asp.Net控件

LINQ 查询返回实现了Ienumerable接口的结果,这个接口也是Asp.Net服务器控件支持对象绑定的接口。这就意味着,你可以绑定任何LINQ,LINQ TO SQL,或者LINQ TO XML查询的结果到任何的Asp.Net控件。

举个例子,你可以像下面这样在.aspx页面中声明一个<asp:gridview>的控件,

然后,可以像下面这样绑定我们已经写好的LINQ TO SQL查询的结果到GridView中:

这样会产生像下面这样的一个页面:

构造我们的查询结果

现在当我们运行我们的Product查询时,默认地,我们将获取所有所需列的数据以填充Product实体类。

举个例子,这个查询获取Products:

结果是所有的数据都被返回了。

通常,我们仅仅想要返回每个Product数据的一个子集。我们可以使用新的、LINQ 和新C#/VB编译器所支持的数据构造特性去指明我们仅仅想要一个数据的子集,这个可以通过像下面这样修改我们的LINQ TO SQL查询来完成。

这样从我们的数据库将仅返回这些数据(如同我们的debug查看器所显示的)。

LINQ TO SQL比较酷的地方是:在构造数据的时候,可以完全利用数据模型类的联系。这就使我可以写出非常有用(也非常高效)的数据查询。举个例子,下面的查询获取来自Product实体的ID和Name,此Product下的订单的总数,然后结算每个Product的订单的税金总和。

上面“Revenue”属性右侧的表达式是使用由LINQ所提供的“Sum”扩展方法的一个例子。它使用一个返回每个产品订单项的值的 Lambada 表达式 作为一个参数。

LINQ TO SQL是非常智能的,并可以将上面的LINQ表达式在求值时 转换成下面的 SQL语法(如果我们的debug查看器所显示的)。

上面的SQL将会在SQL Server上对所有的NumOrders和Revenue的值进行计算,并仅从数据库获取下面所显示的数据(这使得它运行得非常快)。

我们可以将查询结果绑定到Gridview控件上以产生一个不错的用户界面。

顺便说一下,以免你不断猜测,当你在写这些LINQ构造查询时,你可以在VS2008中获得完全的智能提示。

在上面的例子中,我声明了一个使用对象初始化去构造和定义结果结构的匿名类型。真正酷的地方是:在同这些匿名结果序列打交道的时候,VS2008同样提供了完全的智能提示、编译检测和refactoring支持。

对查询结果进行分页

Web环境中最常见的一个需求就是高效地对用户界面层数据进行分页。LINQ 对两个使分页又简单又高效的扩展方法提供内置的支持,这两个方法是 Skip() 和 Take()。

我们可以使用下面的Skip()和Take()方法,指明我们仅想返回10个Product对象 – 从我们定义的作为参数的初始Product行开始。

注意上面,我没有将Skip()和Take()添加到初始的Products查询声明上,而是在后面添加到查询上(当绑定到GridView数据源时)。常有人问我“这样不是说查询首先从数据库中返回所有的数据,然后在(不好的)中间层中再进行分页?”不会的。原因是LINQ使用一种延迟执行模型 – 这就意味着查询并不实际的执行,直到你试图遍历结果的时候。

这种延迟执行模型的好处之一是,它可以让你在代码语句间非常好地进行查询组合(这样就提高了代码可读性)。它同样可以使你从其他查询中组合查询 – 这样就使一些非常灵活的查询组合和重用的情况成为可能。

一旦我定义好上面的BindProduct()方法,我可以在页面中写出下面的代码以获得来自Querystring的起始索引,并让gridview中的Products分页显示。

这样将呈现给我们一个Products页面,筛选出那些有5个或者以上订单的Products,动态显示计算的Product数据,并且可以通过querystring参数来进行分页。

注意:当使用SQL 2005进行开发的时候,LINQ TO SQL将使用ROW_NUMBER() 函数来进行数据库中的所有分页逻辑。这就确保了在执行上面的代码时,当前显示页只有10行我们所需要的数据从数据库中返回。

这就使得对大型数据序列进行分页的时候更加高效和容易。

总结

对于LINQ TO SQL提供的一些很酷的数据查询方式,希望上面的这些步骤能提供一个好的概览。想要学习更多的LINQ表达式和由VS2008中的C#、VB编译器所支持的新语言语法,请阅读下面这些我更早时发布的随笔:

l         自动属性,对象初始化器和集合初始化器

l         扩展方法

l         Lamabada表达式

l         查询语法

l         匿名类型

在我LINQ TO SQL系列的下一篇随笔中,我将介绍我们如何清楚地对我们的数据模型类添加验证逻辑,并且演示我们如何使用它封装业务层逻辑,这些业务逻辑在每次我们进行更新、插入或者删除数据的时候都会运行。然后我将解释更高级的Lazy和eager加载查询场景(Lazy and eager loading query scenarios),如何使用新的<asp:LINQDataSource>控件来支持Asp.Net控件的声明式数据绑定,乐观并发错误处理,以及其他更多内容。

[译]LINT TO SQL 介绍(数据库查询) - Part.3的更多相关文章

  1. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

  2. 优化SQL Server数据库查询方法

    SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列 ...

  3. 50种方法优化SQL Server数据库查询

    查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 ...

  4. sql server数据库查询取出重复数据记录

    问题:博主在2011年6月,广东技术师范大学大四的时候,从学校计算机科学学院网站看到招聘信息并到广东中原地产IT部面试,很清楚记得当时的面试题目:怎么从数据库里面查询重复记录. 解决方案:在sql s ...

  5. (五)SQL入门 数据库查询

    什么是查询?查询就是Select语句对数据库的探究. 查询是一种目的,一种需求,一种期望.是Select语句去实现的.Select语句不是只是指select语句,而是多个子句一起使用得组合. sele ...

  6. sql server数据库查询同义词

    查询数据库同义词: select * from sys.synonyms, 查询同义词个数:select count(1) from sys.synonyms

  7. LinQ to sql 各种数据库查询方法

    1.多条件查询: 并且 && 或者 || var list = con.car.Where(r => r.code == "c014" || r.oil == ...

  8. sql server数据库查询超时报错

    报错信息如下: 链接服务器"DBJointFrame"的 OLE DB 访问接口 "SQLNCLI10" 返回了消息 "查询超时已过期". ...

  9. sql server数据库查询链接服务器

    服务器对象->链接服务器: 或者 select  * from sys.servers: 找到服务器对象名称 select  * from [服务器对象名称].[数据库名称].dbo.[表名]:

随机推荐

  1. SDUT1466双向队列

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=1466&cid=1182 题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列 ...

  2. Oracle 6 - 锁和闩 - 并发问题和隔离级别

    并发带来的问题 1.脏读dirty read 脏读的问题是transaction读到了没有被提交的数据.例如,T1更新了data1,还没提交,这时T2读取了更新后的data1, 用于计算和更新别的值, ...

  3. Project Euler 97 :Large non-Mersenne prime 非梅森大素数

    Large non-Mersenne prime The first known prime found to exceed one million digits was discovered in ...

  4. linux 防火墙iptables简明教程

    前几天微魔部落再次遭受到个别别有用心的攻击者的攻击,顺便给自己充个电,复习了一下linux下常见的防火墙iptables的一些内容,但是无奈网上的很多教程都较为繁琐,本着简明化学习的目的,微魔为大家剔 ...

  5. 不重启使XP环境变量生效

    不重启使XP环境变量生效 http://www.pkghost.cn/wz/sort0185/8874.html 在“我的电脑”->“属性”->“高级”->“环境变量”中增加或修改环 ...

  6. WCF入门(五)---创建WCF服务

    使用Microsoft Visual Studio2012创建WCF服务,理解如下所有必要的编码,更好地创建WCF服务的概念,这里做一个简单的任务. 启动Visual Studio 2012. 单击新 ...

  7. 从unity3d官网下载教程

    http://unity3d.com/learn/tutorials/projects/tanks-tutorial 官网的教程提供的下载链接https://www.assetstore.unity3 ...

  8. Android开发之定义接口暴露数据

    写了一个网络请求的工具类,然后想要获取到网络请求的结果,在网络工具类中写了一个接口,暴露除了请求到的数据 代码: package com.lijingbo.knowweather.utils; imp ...

  9. [HDOJ4738]Caocao's Bridges(双联通分量,割边,tarjan)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 给一张无向图,每一条边都有权值.找一条割边,使得删掉这条边双连通分量数量增加,求权值最小那条. ...

  10. [HDOJ2874]Connections between cities(LCA, 离线tarjan)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 这题有不连通的情况,特别注意. 觉得是存query的姿势不对,用前向星存了一遍,还是T…… /* ...