【原文地址】Using LINQ to SQL (Part 1)
【原文发表日期】 Saturday, May 19, 2007 12:41 AM
在过去的几个月中我写了一系列涵盖了VS和.NET Framework Orcas版中的一些新特性的帖子,下面是这些帖子的链接:
以上的语言特性帮助数据查询成为一等编程概念。我们称这个总的查询编程模型为“LINQ”--它指的是.NET语言级集成查询。
开发者可以在任何的数据源上使用LINQ。他们可以在他们选择的编程语言中表达高效的查询行为,选择将查询结果转换或构形成他们想要的任何格式,然后非常方便地操作这个结果集。有LINQ功能的语言可以提供完全的类型安全和查询表达式的编译时检查,而开发工具则可以提供在编写LINQ代码时完全的智能感知,调试,和丰富的重构支持。
LINQ支持一个非常丰富的的扩展性模型,该模型将有助于对不同的数据源生成不同的高效运算因子(domain-specific operators)。.NET Framework的Orcas版本将发布一些内置库,这些库提供了针对对象(Objects),XML,和数据库的LINQ支持。
什么是LINQ to SQL?
LINQ to SQL 是随.NET Framework Orcas版一起发布的O/RM(对象关系映射)实现,它允许你用.NET 的类来对一个关系型数据库建模。然后你可以用LINQ对数据库进行查询,以及进行更新/插入/删除数据的操作。
LINQ to SQL完全支持事务,视图和存储过程。它还提供了一种把数据验证和业务逻辑规则结合进你的数据模型的便利方式。
使用LINQ to SQL对数据库建模:
Visual Studio Orcas版中提供了一个LINQ to SQL设计器,该设计器提供了一种简易的方式,将数据库可视化地转换为LINQ to SQL对象模型。我下一篇博客将会更深入一些来介绍怎么使用该设计器(你可以观看我一月份时录制的这个关于如何从头开始创建LINQ to SQL模型的录像)。
通过LINQ to SQL设计器,我可以方便地设计出如下所示的Northwind数据库的示例模型:
上图定义了四个实体类:Product, Category, Order 和 OrderDetail。每个类的属性都映射到数据库中相应表的字段,类实体的每个实例代表了数据表中的一行记录。
在上图中,四个实体类间的箭头代表了不同实体间的关联/关系。它们主要是根据数据库中的主键/外键关系生成的。设计器上的箭头的指向表明了该关系是一对一还是一对多的关系。基于此,强类型的属性将会被加入到实体类中。例如,上边的Category类和Product类之间有一个“一对多”的关系。这意味着Category类将有一个"Products"属性,该属性代表了在该类中所有的产品对象的集合。而Product类将会有一个"Category"属性来指向一个Category类的实例,该Category类的实例表明了了产品所属的类别。
上图中LINQ to SQL设计器的右侧列出了与我们的数据库模型交互的存储过程。在上边的例子中,我添加了一个“GetProductsByCategory”存储过程。它有一个categoryID作为输入参数,返回一个产品实体序列作为结果集。下面的代码将展示如何调用该存储过程。
理解DataContext类
当你点击LINQ to SQL设计器上的“保存"按钮时,Visual Studio将会保存我们建立的代表了实体和数据库关系的各个类。针对加入到我们的解决方案的每一个LINQ to SQL设计器文件,同时也会生成一个自定义的DataContext类。这个DataContext类是我们从数据库中查询实体或者进行更改操作的主要渠道。生成的DataContext类将含有一些属性,对应于我们在数据库中建了模的每个数据表,以及一些方法,对应于我们添加的每个存储过程。
例如,下图就是基于我们上边设计的模型而生成的的NorthwindDataContext类:
LINQ to SQL 代码例子
用LINQ to SQL 设计器对我们的数据库建模之后,我们就可以很方便地编写代码对数据库进行操作了。下边是一些展示了常见的数据库操作的代码例子:
1) 从数据库中查询Products
下面的代码用LINQ to SQL 查询语法来获取Product对象的IEnumerable序列。注意代码是如何通过Product/Category关系来仅查出那些类别是"Beverages"的产品的:
C#:
VB:
2) 更新数据库中的一条产品记录
下面的代码示范了如何从数据库中查询出单一的一条产品记录,更新它的价格,然后将改动保存至数据库:
C#:
VB:
注意:VB在Orcas Beta1中尚不支持Lambda。但是在Beta2中,它就会支持了--那时代码就会能写得更为简洁一些。
3) 向数据库中插入一条新的Category和两条新的Products
下面的代码示范了如何生成一个新的分类,然后生成两条和该分类相关联的产品,然后将这三条记录保存到数据库中。
注意下边,我不用手工去维护主/外键关系,取而代之的是,我只向分类对象的“Products”集合中添加了两个Product记录,然后把该Category对象添加到DataContext的“Categories”集合中,LINQ to SQL将知道自动为我持久适当的PK/FK的关系。
C#
VB:
4) 从数据库中删除Products
下面的代码示范了如何从数据库中删除所有的玩具产品:
C#:
VB:
5) 调用存储过程
下面的代码示范了如何不使用LINQ查询语法,而是通过调用我们在上面向数据模型中添加的“GetProductsByCategory”存储过程来查询Product实体。注意,一旦我查询出了Product结果集,我可以更新/删除它们,然后再调用 db.SubmitChanges()来将这些更新提交到数据库。
C#:
VB:
6) 在服务器端分页查询Products
下面的代码示范了如何通过LINQ查询语法实现高效的服务器端数据库分页查询。通过使用下面的Skip()和Take()操作符,我们从数据库中只查询出从200行开始的10条记录:
C#:
VB:
总结
LINQ to SQL提供了一种很棒的、干净利索的方法来为你的应用程序来建立数据层。一旦你定义了数据模型,你就可以方便而且有效地对它进行查询,插入,更新和删除。
希望以上的介绍和代码例子刺激了你的胃口,希望了解到更多东西。在接下来的几周里我会在该系列中更具体地探讨LINQ to SQL。
希望本文对你有所帮助,
Scott