Linq-To-Sql-Part_2-Define-Data-Model-Class
图文结合教你用好LINQ to SQL

不过谈到.NET平台,ORM框架似乎相对混乱了点。
很多朋友问我的时候,往往会这样问:NHibernate、NBear和Castle该选择哪个?而当我反问:为什么不适用微软自带的Linq to SQL 呢?对方经常会迷茫和不解。
我觉得这是个很奇怪的现象。
依照我个人的实践,我认为当需要快速构建一个中小型项目时,Linq to SQL是一个很好的选择。
你至少有以下理由可以选择它:i. 它是微软自己的产品,和.NET平台有着天生的适应性。
如果你使用.NET Framework3.5和 VS2008开发环境,它本身就集成在里面了,同时VS2008对于Linq to SQL 给予了诸多方便的支持。
使用它,你不仅在开发和部署时不用考虑第三方库,更可以尽情享受VS2008带来的种种方便。
ii. 上手十分容易,使用十分轻松,通常,你不需要编写一行代码,也不用写任何XML 配置,完全通过可视化拖拽就能完成ORM层的构建。
iii. 功能丰富,使用便捷。
当轻松构建好ORM层后,你就可以更轻松的操纵数据库了。
Linq to SQL提供了丰富的功能,完全可以满足日常数据访问的需求。
使用方法也非常简单、灵活。
有这么好的理由,我真想不通为什么那么多人不愿去选择它。
我想来想去,也许有两个重要原因,一是把LINQ和Linq to SQL混为一谈了,二是受前段时间“LINQ已死”的误导,觉得微软已经抛弃Linq to SQL了。
关于这两点,我就不细说了,简略澄清一下:首先,LINQ是从.NET Framework3.0开始,.NET平台上引入的一种新式语言特性,狭义一点,你可以讲它理解成一种新式语法,主要是针对迭代数据操作的,所以,也许LINQ 叫做“数据迭代引擎(Data Iterative Engine)”更合适,之所以不着样命名,我想微软可能不愿意让自己产品的简写为“DIE”吧。
:-)而Linq to SQL是LINQ在数据库访问方面的一个应用框架,完全是两码事。
一步一步学Linqtosql二:DataContext与实体

一步一步学Linq to sql(二):DataContext与实体DataContextDataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入数据库。
DataContext提供了以下一些使用的功能:●以日志形式记录DataContext生成的SQL●执行SQL(包括查询和更新语句)●创建和删除数据库DataContext是实体和数据库之间的桥梁,那么首先我们需要定义映射到数据表的实体。
定义实体类以Northwind数据库为例,上述Customers类被映射成一个表,对应数据库中的Customers表。
然后在类型中定义了三个属性,对应表中的三个字段。
其中,CustomerID字段是主键,如果没有指定Column特性的Name属性,那么系统会把属性名作为数据表的字段名,也就是说实体类的属性名就需要和数据表中的字段名一致。
现在,创建一个页面,然后在页面上加入一个GridView控件,使用下面的代码进行绑定数据:使用DataContext类型把实体类和数据库中的数据进行关联。
你可以直接在DataContext 的构造方法中定义连接字符串,也可以使用IDbConnection:之后,通过GetTable获取表示底层数据表的Table类型,显然,数据库中的Customers 表的实体是Customer类型。
随后的查询句法,即使你不懂SQL应该也能看明白。
从Customers 表中找出CustomerID以“A”开头的记录,并把CustomersID、Name以及City封装成新的匿名类型进行返回。
结果如下图:强类型DataContext强类型数据上下文使代码更简洁:DataContext其实封装了很多实用的功能,下面一一介绍。
日志功能运行程序后在网站所在目录生成了log.txt,每次查询都会把诸如下面的日志追加到文本文件中:应该说这样的日志对于调试程序是非常有帮助的。
一步一步学Linq to sql

意义不是很大,纯粹解决机械劳动。编译器自动为你生成get、set操作以及字段,并且你不能使用字段也不能自定义get、set操作,不过你可以分别定义get和set的访问级别。
对象初始化器
publicclassPerson
{
publicstringusername {get;set; }
Table<Customer> Customers = ctx.GetTable<Customer>();
GridView1.DataSource =fromcinCustomerswherec.CustomerID.StartsWith("A")selectnew{顾客ID=c.CustomerID,顾客名=,城市=c.City};
Console.WriteLine("username:{0} age:{1}", ername, data.age);
匿名类型允许开发人员定义行内类型,无须显式定义类型。常和var配合使用,var用于声明匿名类型。定义一个临时的匿名类型在LINQ查询句法中非常常见,我们可以很方便的实现对象的转换和投影。
今天就说到这里,再见!
DataContext与实体
DataContext
DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入数据库。
DataContext提供了以下一些使用的功能:
?以日志形式记录datacontext生成的sql?执行sql包括查询和更新语句?创建和删除数据库datacontext是实体和数据库之间的桥梁那么首先我们需要定义映射到数据表的实体
linq转化为sql语句的方法

linq转化为sql语句的方法Linq转化为SQL语句的方法概述Linq(Language Integrated Query)是微软推出的一种用于查询和操作数据的统一编程模型。
它可以在不同的数据源上执行查询,例如关系型数据库、XML文档等。
在开发过程中,我们常常需要将Linq 表达式转化为相应的SQL语句,以便对数据库进行操作。
本文将详细介绍多种将Linq转化为SQL语句的方法。
1. LINQ to SQL基本概念LINQ to SQL是一种将LINQ查询转化为SQL语句的方法。
它是Entity Framework的一部分,提供了一种直接在.NET应用程序中使用对象来表示和操作关系型数据库的方式。
在LINQ to SQL中,可以通过DataContext对象来执行查询,并将查询结果转化为SQL语句。
示例代码using System;using ;using ;public class Program{public static void Main(){// 创建DataContext对象,连接数据库DataContext context = new DataContext("Data Sour ce=.;Initial Catalog=MyDatabase;Integrated Security=True ");// 创建查询表达式var query = from c in <Customer>()where == "Beijing"select c;// 执行查询并获取SQL语句string sql = (query).CommandText;// 输出SQL语句(sql);}}2. Entity Framework基本概念Entity Framework是微软推出的一种对象关系映射(ORM)工具,可以映射.NET对象与数据库中的表、视图等关系。
LINQ to SQL

LINQ查询的目的是从指定的数据源中查询满足符合特定条件的数据元素,并且通过根据需要对这些查询的元素进行排序、连接等操作。
所以LINQ查询包含如下几个主要元素:•数据源:数据源表示LINQ查询将从哪里查找数据,它通常是一个或多个数据集,每个数据集包含一系列的元素。
数据集是一个类型为IEnumerable<T>或IQueryable<T>的对象,可以对它进行枚举,遍历每一个元素。
此外,它的元素可以是任何数据类型,所以可以表示任何数据的集合。
•目标数据:数据源中的元素并不定是查询所需要的结果。
目标数据用来指定查询的具体想要的是什么数据。
在LINQ中,它定义了查询结果数据集中元素的具体类型。
•筛选条件:筛选条件定义了对数据源中元素的过滤条件。
只有满足条件的元素才作为查询结果返回。
筛选条件可以是简单的逻辑表达式表示,也可以用具有复杂逻辑的函数来表示。
•附加操作:附加操作表示一些其它的具体操作。
比如,对查询结果进行分组等。
其中,数据源和目标数据库是LINQ查询的必备元素,筛选条件和附加操作是可选元素。
2.用from子句指定数据源每个LINQ查询都以from子句开始,from子句包括以下两个功能。
•指定查询将采用数据源。
•定义一个本地变量,表示数据源中单个元素。
单个from子句的编写格式如下所示。
其中dataSource表示数据源,localVar 表示单个元素。
from localVar in dataSource3.用select子句指定目标数据select子句指定在执行查询时产生结果的数据集中元素的类型,它的格式如下所示:select element4.用where子句指定筛选条件在LINQ中,用where子句指定查询的过滤条件,它的格式如下:where expression其中,express是一个逻辑表达式,返回布尔值“真”或“假”在LINQ查询中,还可以使用多个并列的where子句来进行多个条件过滤。
第十六章 LINQ to SQL

1-11
1-3
LINQ to SQL和
LINQ
LINQ查询基础 LINQ对象模型
LINQ to SQL 支持程序
DataSet/DataTable DataAdapter DataCommand DataConnection 数据库提供程序
多种类型数据库 SQL Server、Oracle、Access等
1-10
修改数据库记录
DataContext类作为对象模型和数据库模型之间的桥梁,在 提供读取数据库接口的同时还提供了数据库修改接口。通过 DataContext类修改数据通常包含以下4个步骤: • (1)创建对象关系模型,创建和数据库对应的 DataContext类型。 • (2)通过DataContext类提供的数据表对象获取数据记录 • (3)通过设置类的属性来修改记录的值。 • (4)通过DataContext类的SubmitChanges()方法将修 改后的数据提交到数据库。 例:将所有默认密码666666改为ABCDEF
1-5
LINQ to SQL查询执行流程
应用程序
LINQ to SQL
DataAdapter DataCommand DataConnection
数据库
LINQ 查询
SQL命令
查询结果
对象集合
DataSet DataReader
1-6
O/R设计器
Visual Studio 2010为开发人员提供了一套自动化的对象关系 设计器——O/R设计器。O/R设计器提供一个可视化设计界面, 通过向导自动创建基于数据库中对象的LINQ to SQL实体类和 关系,并且可以像编辑类图和数据库关系图那样编辑各个类、 成员等。 O/R设计器还提供了相关功能,用于将存储过程和函数映射到 DataContext方法以便返回数据和填充实体类。最后, O/R 设 计器提供了对实体类之间的继承关系进行设计的能力。 例:使用O/R设计器。
LINQ体验(9)——LINQ_to_SQL语句之Insert、Update、Delete操作

Address = c1.Address, City = c1.City, CompanyName = panyName, ContactName = c1.ContactName, ContactTitle = c1.ContactTitle, Country = c1.Country, CustomerID = c1.CustomerID, Fax = c1.Fax, Phone = c1.Phone, PostalCode = c1.PostalCode, Region = c1.Region }; Customer tempcust = tempdb.Customers.Single(c => c.CustomerID == "ANTON"); foreach (Order o in tempcust.Orders) { deserializedOrders.Add(new Order {
foreach (var p in q) {
p.UnitPrice += 1.00M; } db.SubmitChanges();
Delete
1.简单形式
说明:调用 DeleteOnSubmit 方法即可。
OrderDetail orderDetail = db.OrderDetails.First (c => c.OrderID == 10255 && c.ProductID == 36);
Order order = db.Orders.First(x => x.OrderID == 10248); OrderDetail od =
使用LINQ to SQL访问数据库

Copyright@2009 College of ITSoft (HDU)
Version No: 2.0
16
使用Object Relational Designer创建实体 1. 选择站点的添加新项 2. 选择LINQ to SQL类 3. 打开Object Relational Designer后将一个或多 个表拖放至Designer面板上
Copyright@2009 College of ITSoft (HDU)
Version No: 2.0
14
手工创ቤተ መጻሕፍቲ ባይዱ实体
using System.Data.Linq.Mapping; [Table] public class TempInfo { [Column (IsPrimaryKey=true)] public string uID { get; set; } [Column(IsPrimaryKey=true)] public DateTime cDate { get; set; } [Column] public double TempAM { get; set; } [Column] public double TempPM { get; set; } [Column] public string Des { get; set; } }
Copyright@2009 College of ITSoft (HDU)
Version No: 2.0
11
C#语言中的子句 语言中的子句
from 指定数据源以及用来迭代数据源的变量 where 过滤查询的结果 select 指定查询结果中的项 group 通过某一关键字对相关的值进行聚合 into 存储聚合中的结果,或连接到一个临时变 量 orderby将查询结果按升序或降序进行排序 join 通过一个关键字,对两个数据源进行连接 let 创建一个临时变量,来表示子查询的结果
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linq To Sql Part.2定义数据模型类ScottGu译者:张子阳jimmy_dev@出处:Linq To Sql (Part.2 – Defining Our Model Classes)术语表Data Model:数据模型Designer:设计器Class Library:类库Client Project:客户端项目Conduit:管道Entity Class:实体类Instance:实例Partial Class:部分类Runtime:运行时Execution logic:执行逻辑RelationShip Associations:关系之间的联系Delay/Lazy:延迟/惰性 加载Prefectched:预获取在我博客上的随笔 LINQ TO SQL Part .1中,我讨论了“什么是LINQ TO SQL”这个问题,并提供了一些可以使用它的基本场景。
在我的第一篇随笔中,我提供了一些代码范例,示范了如何使用 LINQ TO SQL进行一些常见的数据操作任务,其中包括下面几个方面z如何对数据库进行查询z如何更新数据库中的一行z如何在数据库中插入行并给这些行建立关系z如何删除数据库中的一行z如何调用存储过程z如何使用服务器端分页获取数据我使用一个如下图所示的LINQ TO SQL类模型实现了上面的所有操作。
在本文中,也是这一系列的第二篇随笔中,我将更细致地讲解如何创建上图所示的LINQ TO SQL数据模型。
LINQ TO SQL, LINQ TO SQL 设计器,以及所有我在这篇随笔中将要讨论的特性都将作为.Net 3.5的一部分伴随着 Visual Studio “Orcas”版本一起发布。
通过下载 Visual Studio “Orcas” Beta 1 或者 Visual Web Developer Express “Orcas”Beta1,你可以按我下面将要讲解的步骤一步步的学习。
它们可以和VS2005同时安装在同一台机器上。
创建一个新的 LINQ TO SQL数据模型你可以在Visual Studio中点击 “添加新项”选项卡,并且选择其中的“LINQ TO SQL”来添加一个LINQ TO SQL 数据模型到一个 类库 或者 Windows客户端项目中。
选择“LINQ TO SQL”项目将会自动运行LINQ TO SQL设计器,并允许你使用它去创建表现关系数据库结构的类。
它同样也将创建一个强类型的“DataContext”类,这个类的属性代表着我们为之建立模型的数据库中的每张表和我们所建模型的每个存储过程。
如同我在 Part .1 那篇随笔中所描述的那样,DataContext类是一个主要的管道,我们通过它来对数据库中的实体进行查询以及将对数据的更改存回数据库。
下面是一个空的 LINQ TO SQL ORM (NOTE:对象/关系映射,可以参阅 Part.1)的截图,也是你在创建一个新的 LINQ TO SQL 模型之后将会看到的。
实体类LINQ TO SQL 使你可以创建 由类到数据库,或者由数据库到类的映射。
这些类通常都被称作“实体类”,而他们的实例,被叫做“实体”。
实体类映射到数据库中的表。
实体类的属性通常映射到表的字段。
每个实体类的实例都代表了数据库表中的一行。
由LINQ TO SQL 定义的实体类 不需要 继承某个特定的基类,这就意味着你可以让它从任何你想要的对象上继承。
所有通过使用 LINQ TO SQL 设计器创建的类都被定义为“部分类”,这意味着你可以有选择的深入代码,给它们添加一些额外的属性、方法、事件。
与由VS2005中提供的 DataSet/TableAdapter 方式不同,当使用LINQ TO SQL 设计器时,你在定义你的数据模型和数据访问层时不需要给出 SQL 查询语句。
相反,你只把精力集中在定义你的实体类,它们是如何 映射自数据库/映射到数据库 以及 它们之间的关系。
LINQ TO QL OR/M 实现将会在你与数据库实体交互或者使用这些实体时体贴地在运行时为你创建合适的SQL执行逻辑。
你可以使用LINQ查询语法明确地指明你想要如何对你的数据模型以一种强类型的方式进行查询。
当你添加了上面所示的来自“Northwind”的两个表(Categories 和 Products)和视图(Invioces)到LINQ TO SQL 设计器中。
根据底层的数据库构架,你将会自动获得下面所示的三个实体类。
使用上面定义的数据模型类,我现在可以运行所有在 Part 1 中演示的代码范例了(除过存储过程)。
我不需要写任何额外的代码或者配置,就可以实现查询、添加、删除、修改以及服务器端分页的操作。
命名和Pluralization当你使用LINQ TO SQL设计器的时候,应该注意到的一件事就是,当它在根据你的数据库构架为你自动地添加实体类的时候,它也将会自动地为你“Pluralize”不同的表和字段。
举个例子,我们上面例子中的“Products”表产生了一个“Product”类,而“Categories”表产生了一个“Category”类。
这种类的命名有助于使你的模型与.Net命名规范相一致,并且我经常会发现使用编辑器做这事是非常方便的(尤其是在为你的模型中添加大量的表的时候)。
如果你不喜欢设计器生成的表或者字段的名字,当然,你可以修改它们并且将它们改成任何你想要的名字。
你可以通过编辑设计器中的实体/属性名来修改,也可以通过属性栏。
NOTE:Pluralization,找不到合适的词翻译,根据上下文,可以理解成 “规范命名”。
设置 实体/属性/联系 的名字与你数据库构架中的名字不一样的能力,在很多情况下非常有用,特别是:1.当你的后台数据库 表/字段 的名称改变的时候。
因为你的实体模型可以拥有和后台构架不同的名字,你可以决定只更新你的映射规则,但是却不更新你的应用程序或者查询代码,以便使用这个新的 表/字段 名字。
2.当你有一个数据库构架,其中的对象名字不是非常的“干净”。
比如说,使用诸如“au_lname”和“au_fname”这样的名字作为你的实体类的属性名,你可以在你的实体类中将它们更改为“LastName”和“FirstName”,并且根据这个名字进行开发(而不需要更改数据库中的字段名字)。
关系之间的联系当你从服务器栏拖动一个对象到LINQ TO SQL设计器中时,Visual Studio将会检查对象的 主键/外键 关系,并且根据这个关系在它创建的不同实体类之间自动的创建一个默认的“关系之间的联系”。
举个例子,当我从Northwind中添加Products和Categories表到我的LINQ TO SQL 设计器中的时候,你可以看到它们之间的一个一对多的关系建立了(这个是由设计器中的一个箭头示意的)。
上面的联系将会使得Product实体类有了一个“Category”属性,通过这个属性,开发者可以访问一个给定Product的Category。
它也使得Category类有了一个“Products”集合,通过这个集合开发者可以获得一个给定Category的所有Products。
如果你不喜欢设计器建模或者命名关系的这种方式,你可以覆盖它。
单击设计其中表示关系的箭头,并且通过属性栏找到它的属性,然后重命名、删除或者修改它。
延迟/惰性加载LINQ TO SQL 允许开发者指定实体中的属性在第一次访问的时候应该是 预获取 还是 延迟/惰性加载。
你通过在设计器中选择任意实体的属性或者关系来为实体的属性定义默认的预获取/延迟加载 规则,然后将属性栏中的“Delay Loaded”属性设置成True或者false。
举个例子以说明什么时候我们需要这样做。
考虑一下我们刚才建模的“Category”实体类。
“Northwind”中有一张“Categories”表,这个表中含有一个“Picture”字段,其中存有(很可能是很大的)表示种类的二进制数据,而当我使用它的时候我只想获取数据库中的二进制数据(而不是进行一个查询将Category的名字列出来)。
可以通过在设计器中选择它,然后在属性栏中设置Picture的迟加载值来进行配置。
使用存储过程LINQ TO SQL 允许你有选择的对存储过程进行建模,将它作为 DataContext 类中的方法。
举个例子,假设我们定义了一个下面这样简单的存储过程,以根据CategoryId获取Product的信息:我可以使用Visual Studio中的服务器面板 拖放 存储过程到 LINQ TO SQL设计器中,以便添加一个强类型的方法,这个方法用于调用这个存储过程。
如果我将存储过程拖到设计器的“Product”实体,LINQ TO SQL 设计器将声明这个存储过程返回一个Ienumerable<Product>:然后,我可以使用LINQ 查询语法(这将产生一个实际的SQL查询语句),或者,我可以调用上面添加的存储过程来从数据库中获取Product。
使用存储过程进行更新/删除/插入数据默认情况下,在你插入/更新/删除实体的时候,LINQ TO SQL将会自动创建合适的SQL表达式。
举个例子,你写下如下的LINQ TO SQL代码以便更新 “Product”实例的一些值。
默认情况下,当你提交更改时,LINQ TO SQL将会为你创建合适的“更新”语句(我会在以后的随笔中详细讨论)。
你也可以有选择的定义和使用自定义的 INSERT、UPDATE、DELETE 存储过程。
对这些进行设置,点击LINQ TO SQL 设计器中的实体类,并且在它的属性栏中在 Delete/Update/Insert 属性中点击“…”,然后选择特定的预先写好的存储过程。
改变上面设置做的好处是它纯粹只是在LINQ TO SQL的映射层上进行,这就意味着我之前示范的Update代码不需要做任何修改就可以继续使用。
这也就避免了即使在后来使用自定义的存储过程,开发者也不需要改写代码。
总结LINQ TO SQL 提供一种良好、清爽的方式对你应用程序中的数据层进行建模。
一旦你定义好你的数据模型,你可以简单、高效的通过它实现查询、插入、更新、删除。
通过使用Visual Studio和Visual Web Developer Express内置的LINQ TO SQL设计器,你可以非常快速地创建和管理你的LINQ TO SQL数据模型。
LINQ TO SQL设计器同样提供很大的灵活性,允许你自定义默认的行为,并且可以覆盖/扩展这个系统以适应你的特殊需求。
在接下来的随笔中,我将使用我们刚才创建的这个数据模型,深入地探讨查询、插入、更新和删除的特性。