linq世界走一走(LINQ TO SQL)
前言:作为linq的一个组件,同时作为ADO.NET的一个组成部分,LINQ TO SQL提供了将关系数据映射为对象的运行时基础结构.
LINQ TO SQL是通过将关系数据库对象的数据模型(如一个数据表)映射为开发人员所选编程语言中定义的对象模型来工作.所以需要在c#中定义的一个公共类.公共类的定义和映射是通过使用LINQ中的TableAttribute对类进行注释,并将SQL Server中要映射的表的名称传递给属性的Name来实现.这样就完成了关系映射,将一个数据模型映射到一个对象模型.下一步是构建用于检索数据库中对象和数据的通道.通道的创建是使用DataContext类来完成的.DataContext类是System.Data.Linq名称空间的一部分,其目的是把请求从.NET对象转换为SQL查询,然后将查询结果重组到对象中.
例如:DataContext context=new DataContext("数据库连接").它是使用集成的安全机制连接到数据库.DataContext的使用方式同ADO.NET连接非常类似,因为它也是使用连接或连接字符串进行初始化的.
对数据表的访问是通过使用已定义的DataContext类的GetTable方法来实现的,如下所示:Table contact=context.GetTable(); 这样就可以完完全全使用LINQ操纵contact这个类来操纵数据库了.
LINQ TO SQL对象模型为使用和管理关系对象提供了基本元素.正是通过这个模型,关系模型才可以映射到开发人员的编程语言中并表达出来.在LINQ TO SQL对象模型中,数据库命令并没有直接作用到数据库.开发人员只需要改变对象模型范畴内的值并执行其中的方法即可.LINQ TO SQL将这些变化或方法转换成适当的SQL命令并将它们传送给在其上执行的数据库.对象模型通过其与数据库和数据库模型的关系来执行给定的任务.
基于属性的映射
从SQL Server对象到对象模型的映射均同属性有关.这种基于属性的方法在LINQ TO SQL中大量使用,以有效地将数据库对象映射到以用户所选的编程语言定义的对象模型.创建属性映射有如下三种方法:可能鹏哥他们用的就是如下三种的一种.
⑴Object Relational Designer(对象关系设计器,ORD)工具
⑵SQLMetal命令行工具
⑶编写代码手工创建
基于属性的映射现在由System.Data.Linq.Mapping名称空间支持
1.使用Database属性
Database属性用于在定义数据库和对象之间的映射时指定数据库的名称.这个属性具有一个Name特性,用来保存要为其定义映射的数据库的名称.[Database(Name="AdventureWorks")]
此属性是可选的,但使用时必须指定Name属性.通常情况下,当在连接字符串中没有提供数据库的名称时会用到此特性
2.映射表
在LINQ TO SQL中的数据表是由实体类表示的.实体类就如同我们定义的标准类,但它使用一个特殊的标记进行注释,此标记将该类映射或关联到一个特定的数据库表.LINQ TO SQL需要table属性,该属性将实体类(被指定为一个实体的类)映射到一个表或试图.Table属性也只包含一个Name特性,用于指定关系表或视图的名称.
[Table(Name="AdventureWorks.Employee")].记住,只有被映射到数据库表的实体类才可以被保存到数据库.另外那些用Table属性标注的类被LINQ TO SQL视为永久类?(啥意思)
3.映射列
数据表被映射到实体类之后,必须将表的列映射到类的属性.Column属性将数据库表的一个列映射到一个实体类的成员.可以指定多个字段或特性来表示数据库中的列,而且只有那些被映射的字段或特性才可以从数据库中进行检索.属性的特性如下:
[Column(DBType="varchar(50)",CanBeNull=false)]
public string NationalIDNUmber;
注意:1.没有被标记为列的字段被认为是临时信息,也就是说,它们被假定为不是永久存在的,而且不会被提交给数据库.
2.只有已定义的列会被用来将数据保存到数据库表中并从数据库中检索数据.
4.映射关系
对数据库的查询通常需要从多个数据表(而不是单个表)获取信息.这些表通常使用主键/外键关系来联接.LINQ TO SQL的Assocation属性可以表示这些数据库的关联.如下描述了Assocation属性的特性.可以使用它们来定制关联.
下面的示例定义个关联
[Association(Name="FK-Employee-Contact_ContactID",Storage="_Employee",ThisKey="ContactID",IsForeignKey=true)]
public Employee Emp
{
get{return this._Employee.Entity;}
set{return this._Employee.Entity=value;}
}
这个关联将被应用到某个需要引用其相关数据表的表上.
5.映射存储过程
对于存储过程的支持是LINQ TO SQL的强大功能之一这是通过StoredProcedure属性实现的.该属性将数据库中的存储过程映射到一个客户端对象.它只有一个Name特性,用于指定存储过程的名称.下面是该属性的一般语法:
[StoredProcedure(Name="OrdersBySalesPersonID")]
public IEumerable OrdersBySalesPersonID([Parameter(DBTpye="int")] string Param1)
{
IExecuteResults results=this.ExectuteMethodCall(this,((MethonInfo)(MethodInfo.GetCurrentMethod())),Param1);
}
使用LINQ TO SQL可以轻松地将每个数据库对象映射到一个客户端对象,这为开发人员提供了以强类型的方式通过客户端代码访问存储过程的功能.通过此映射,客户端的方法签名产生了与数据库中定义的过程签名的相似性,因此可以使用编程语言的多种特性,如IntelliSense.
6.映射函数
LINQ TO SQL还支持用户自定义的函数.客户端对象和用户自定义的函数均以与存储过程相同的方式进行映射--通过使用属性.(详细情况请参考更多资料)
7.使用Parameter属性
Parameter属性用于映射存储过程中的方法的输入参数,它包含两个特性,
①Name,参数的名称,与数据库中参数同名的字符串
②DbType,数据库的数据类型
Name特性有两种用法;作为输入参数和作为输出参数或返回参数.如下:第一个Parameter属性指定返回参数的类型,第二个则指定输入变量的类型
关系数据基础,顺便巩固一下自己的基础知识
LINQ TO SQL是用来处理关系数据的,归根结底都是在进行CRUD操作:创建(插入),读取,更新或删除数据.所以必须要对关系数据的知识进行掌握.
Ⅰ.主键
主键是唯一确定数据库表中各行记录的一个或一组列.主键中包含的列不能取空值.主键增强了数据表的完整性,可以在创建表或之后修改表的结构时定义主键.一个主键可以被定义成单个或多个列.一个表只能有一个主键.主键最常见的表示形式是一个SQL数据类型(如int类型和bigint类型)的标识列.当在查询中使用主键时,使用该索引可以快速地检索记录.
2.外键
外键定义了两个表之间的关系.一个外键是单个列或一组列,用于在父表和子表之间创建和应用关系或链接.当主键中的一个或多个列(主键表)被另外一个表的一个或多个列(外键表)引用时就创建了外键.正如在上一节中讨论到的,总之,这个表的外键一定是别个表的主键.
外键的约束:如果一个或多个相关表中用到的某个值被删除,约束将决定相关表中的值是否也会被删除\保留或设置为空.
当将一个对象映射到一个外部关系数据对象时,必须指定哪个列是外键.可以在表的定义中定义一个方法并用Association属性来标注该方法.此属性告诉数据表,它是一个外键并将该列指定为外键列.如下:
********LINQ TO SQL查询********
与标准LINQ查询不同,LINQ TO SQL返回的变量类型必须为IQueryable,而标准LINQ查询返回的是IEnumerable类型.如下,展示了LINQ 与linq to sql的异同.大部分是一样的,唯一不同的是处理联接操作的处理方式和查询变量的返回类型:
当执行查询的时候,会涉及到如下几个组件:
⑴LINQ TO SQL API
⑵LINQ TO SQL Provider
⑶ADO Provider
当执行查询的时候,每个组件都起着举足轻重的作用,当执行LINQ TO SQL 查询时,需要执行以下七个步骤来完全查询并返回结果:
⑴LINQ TO SQL API代表应用程序请求执行查询.
⑵LINQ TO SQL API将查询转交给LINQ TO SQL PROVIDRE
⑶LINQ TO SQL PROVIDER将LINQ查询转换成T-SQL.
⑷LINQ TO SQL PROVIDER将新的查询转交给ADO provider以在服务器上运行
⑸执行查询并将结果以DataReader的形式返回给ADO Provider.
⑹ADO Provider将DataReader返回给LINQ TO SQL PROVIDER
⑺LINQ TO SQL PROVIDER将DataReader转换成为可枚举的对象.
㈠DataContext
在执行LINQ TO SQL查询之前,必须建立一个到数据库的连接.在LINQ TO SQL中,可以通过DataContext类创建到数据库的连接.应该将DataContext类和ADO.NET中的sqlConnection类放在相同的层次上来考虑.DataText是创建到数据库连接的媒介,通过它可以从数据库中检索对象提交给数据库.
与SqlConnection类相同,DataContext实例接收一个连接字符串,一旦创建了该连接,就可以通过DataContext从数据库中读取数据并将改动返回给数据库.不过,其中有一个过程是有DAtaContext,而不是SqlConnection完成的.LINQ TO SQL 处理的是对象,DataContext将对象转换为SQL查询,并将返回结果转换为可查询的对象.
㈡强类型的DataContext
建立一个强类型的DataContext非常简单.所需做的工作就是创建一个继承自DataContext类的新类,
public class AdventureWorks:DataContext
{
public AdventureWorks(string connection):base(connection){}
}
创建了DataContext类之后,就可以使用它连接到指定的数据库,如下面的示例所示.在这个示例中,为前面强类型的DataContex指定了与将要使用的数据库同名的名称,在本例中指定的名称是AdventureWorks.因此,在连接字符串中不再需要指定数据库的名称.
AdventureWorks AW=new AdventureWorks("Integrated Security=sspi");
创建强类型的DataContext对象要优于创建非强类型的Data Context对象,因为强类型的数据表对象的使用消除了在查询中使用GetTable方法的必要性.每个数据库表都表示为一个Table集合,可以通过DataContext类的GetTable方法获取.
㈢数据操纵
插入,更新,删除,最后都通过SubmitChanges()提交
㈣存储过程和用户自定义函数
1.映射并调用存储过程
LINQ TO SQL支持对存储过程的映射和调用,这可以通过在对象模型中定义表示存储过程的方法来实现.可以通过应用[Function]属性和任何相关的[Parameter]属性将方法指定为存储过程.被映射的存储过程可以返回行集.并可以使用参数.
2.映射并调用用户自定义函数
********LINQ TO SQL高级查询********
①数据库关系
②已编译查询
③查询执行的位置
④延迟执行与立即执行比较
⑤组合键
⑥只读数据
①如何进行跨键查询
数据库中的关系通常是主键/外键类型,即一个表中的一个列或列的集合被另一个表中的列或集合引用.在关系数据库中,两个表之间的导航是通过联接操作符或操作实现的.在联接操作中,通过在主键和外键应用JOIN操作符将主键表引用为外键表.
LINQ TO SQL中应用相同的联接功能.可以通过用于辅助表示数据库中表之间主键/外键关系的类型来实现.这两种类型是EntitySet和EntityRef范型,其类型均为(of TEntity).这两种类型为一对多中的"多"方提供集合,它们均与[Association]相结合,[Association]属性有助于定义和表示一个关系.
1.EntitySet(of TEntity)
EntitySet类型为一对多关系中"多"方的结果提供集合.换句话说,它意味着所定义的关系是一对多关系.如前所诉,它与[Association]属性结合性使用来定义并表示一个关系.在关系定义中也使用OtherKey特性.它为与当前类(表)的特性(列)想对照的相关类(表)指定特性的名称.
2.EntityRef(of TEntity)
EntityRef类型定义两个表之间的关系,但与EntitySet相反,它用于一对多关系中的"一"方.它也与[Association]属性相结合来定义表示一个关系.
同样,在关系的定义中使用ThisKey特性来指定与当前类(表)的特性(列)相对照的相关类(表)中特性(列)的名称.
3.查询
当跨对象查询时有两种选择:join语句或点符号.它们同样有效.但第二种方法比第一种提供了更好的关系检查.emp.name(点符号,好处能够确定查询结果)
4.已编译查询
已编译查询时指存储在静态变量中的查询,无论何时需要它时都可以执行它
已编译查询通过System.Data.Linq名称空间CompiledQuery类实现.此类有一个Compile方法,通过该方法可以创建一个表示已编译查询的新委托(delegate).
已编译查询的主要优点是不需要每次执行查询时都将其编译一次.它只需要编译一次(当第一次运行时),然后就可以多次使用,即时查询的参数变化了,也不需要重新编译查询.
5.远程查询执行与本地查询执行比较
远程查询:一般在服务器上执行
本地查询:一般在本地缓存执行
远程查询:虽然远程执行依赖于查询,但它通常是最合乎逻辑的选择.它可以让我们利用数据库引擎的优点,如索引.如果数据库有很多记录,最好的选择是远程查询
执行远程查询可以使用两个工具:IQueryable接口和EntitySet类.EntitySet类实现了IQueryable接口,而IQueryable接口保证查询可以远程执行.如上介绍的查询都是远程查询.
远程执行的一个关键好处是可以利用数据库表索引带来的好处,这是在本地执行查询时无法实现的.远程执行也可以保证不会返回不需要的数据.
本地执行:在需要本地执行的情形中可以采用另一种选择.使用EntitySet的Load()方法将所有相关的实体检索到本地缓存中.在下面的示例中,通过EntitySet为Contact类和Employee类定义了一个关系.因此,当加载联系人时,相应的雇员也会同时被加载.
本地执行查询有两个好处.首先,一旦在本地加载了一个数据集,就可以随时对它进行查询,而不需要为了后续的每个查询再去访问数据库.其次,可以对整个数据集进行序列化.
6.延迟数据加载与立即数据加载的比较
可以使用ToList()或ToArray()方法强制一个不会产生单个值的查询立即执行.记住查询时这样执行的:应该使用延迟执行来产生一个值序列,而使用立即执行来返回单个值
7.DataShap类
LINQ TO SQL为在返回父类对象的同时返回相关对象提供了一种方法,此方法同样具有只返回所需对象的好处.这通过DataShap类实现,此类能够定义一个可以在主查询返回的同时返回的子类型.这个类包含一个LoadWith方法,用于在查询执行时指定要返回的子对象.
8.关闭延迟加载
DataContext类的DeferredLoadingEnabled属性会告诉框架不要延迟一对多或一对一关系的加载,它的使用方法如下:
AdventureWorks aw=new AdventureWorks("连接");
aw.DeferredLoadingEnabled=false;
9.组合键
当需要一个以上的属性来唯一标识一个实体,这时候就要用到组合键.当操作符只有单个参数时借助组合键可以在查询中包含多个列.在这些情况下,最好创建一个匿名类型来表示需要传递的多个列的组合.
10.只读数据
如果不打算修改数据,通过告诉DataContext 您希望返回的数据是只读的,就可以得到相当不错的性能提升.要获得只读数据,应将ObejectTrackingEnabled属性设为false,该属性会告诉框架跟踪原始值,将它设为false意味着框架不需要跟踪它的改变,从而可以提高性能.此时是不能调用SubmitChanges方法,否则会抛异常
********实体类********
讲解一部分:
①并发变更和并发冲突
在LINQ to sql中,DataContext对乐观并发提供了内置支持.在乐观并发模式中,只有当自第一次检索数据后数据库的状态未发生改变时,更新才会成功.当满足以下两个条件时,就会在LINQ TO SQL对象中发生冲突
1.应用程序试图将变更写回数据库
2.自从请求数据以后,这个被请求的数据在数据库中已经发生了变更.
例如,在你更改数据库某些数据之前,别人已经更改,这时就会发生并发冲突.如何解决呢?
1.UpdateCheck特性
UpdateCheck特性是[Column]属性的一个特性.他告诉LINQ TO SQL在检测到冲突时如何处理乐观并发冲突.所有那些属性中具有UpdateCheck特性的类的成员均要接受更新检查,这样做主要是帮助检测并发冲突
另一种是选择在try/cacth块中使用RefreshMode枚举.RefreshMode枚举为我们决定如何解决冲突提供了很大的灵活性.也可以使用ConflictMode枚举和ChangeConflictException类.
2.ConflictMode枚举有两个值,
ContinueOnConflict-----尝试所有数据库更新,收集所有并发冲突并在更改完成后将它们返回.
FailOnFirstConflict-----当检测到第一个并发冲突时立即中止更新.
此枚举用在SubmitChanges方法的参数中.
3.ChangeConflictException
当任何冲突发生时都会抛出一个ChangeConflictException异常.用在catch(ChangeConflictException ex){}
4.RefreshMode枚举
RefreshMode枚举让我们能够定义应用程序如何处理乐观并发冲突.DataContext类有个Refresh方法,它使用数据库中的初始数据来刷新对象状态.RefreshMode枚举告诉Refresh在发生冲突时要做什么.
RefreshMode包含以下三个枚举值:
keepChanges-----告知Refresh保留对象中已更改的当前值,但将其他值更新为数据库中的值.
keepCurrentValues-----告知Refresh使用从数据库中检索的值替换当前对象的值.
OverwriteCurrentValues--告知Refresh方法使用数据库中的值覆盖所有当前对象的值.
②Linq To sql 支持三种事务模型:
1.显式的本地事务
2.隐式事
3.显式可分布式事务
********LINQ TO DataSet********
简单来说,DataSet是包含内部数据表的对象.从本质上来讲,DataSet是数据在本地内存中的缓存,且数据一般是从数据库中检索得到.这个缓存让我们可以在连续断开的模式下对DataSet中的模式进行变更,跟踪这些变更,并在应用程序重新连接时将这些变更保存到数据库中.
所以重点是如何用LINQ TO DataSet查询DataSet..............
ADO.NET DataSets唯一欠缺的功能可能就是不具备足够的查询能力.虽然DataSet可以很好地处理所有其他事情,但其查询功能存在限制.当然,DataSet中包含Select,GetParentRow和GetChildRows方法,但这些方法仅提供了基本的查询特性.更多详情请参考文献.
********LINQ TO SQL高级论题(工具)********
Ⅰ.对象关系设计器.
O/R Designer(Object Relational Designer,对象关系设计器)提供了一个图形用户界面,用于创建和管理LINQ TO SQL实体类,实体类间的关系及其映射.通过O/R设计器,可以创建一个应用程序中的实体类映射到数据库中对象(如表和存储过程)的对象模型.与前面的章节手动创建和定义这些映射不同.O/R设计器提供了一个图形用户界面来完成这些任务.
LINQ匆匆忙忙就这么结束了~!在学习LINQ的整个过程中,都觉的写这本书的人写了大量的啰嗦语句.把LINQ夸的太过头了~~~~~~我觉的LINQ对于小项目来说还是不错的.但对于大的项目,例如对数据库操作比较复杂的来说,还是得用原生的T-Sql编程语句.同时不管是大项目还是小项目,只要继承了IEunmerable的集合,利用LINQ操作也是很不错的
linq世界走一走(LINQ TO SQL)的更多相关文章
- Linq世界走一走(LINQ TO XML)
前言:Linq to xml是一种使用XML的新方法.从本质上来说,它采用了多种当前使用的XML处理技术,如DOM和XPath,并直接在.NET Framework内将它们组合为一个单一的编程接口.L ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- Linq之旅:Linq入门详解(Linq to Objects)【转】
http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html Linq之旅:Linq入门详解(Linq to Objects) 示例代码下载:Linq之 ...
- Linq之旅:Linq入门详解(Linq to Objects)(转)
http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html 示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细 ...
- 白话LINQ系列1---什么是LINQ?
一.本系列目标 1.理解LINQ: 2.能写得复杂的LINQ语句(比如:动态查询): 3.理解表达式树及相关概念: 4.熟练运用LINQ写出优美的代码(希望一起努力,最终达到): 二.LINQ为何物? ...
- linq字符串搜索条件,排序条件-linq动态查询语句 Dynamic LINQ
在做搜索和排序的时候,往往是前台传过来的字符串做条件,参数的数量还不定,这就需要用拼sql语句一样拼linq语句.而linq语句又是强类型的,不能用字符串拼出来. 现在好了,有个开源的linq扩展方法 ...
- LINQ之路16:LINQ Operators之集合运算符、Zip操作符、转换方法、生成器方法
本篇将是关于LINQ Operators的最后一篇,包括:集合运算符(Set Operators).Zip操作符.转换方法(Conversion Methods).生成器方法(Generation M ...
- LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法
本篇继续LINQ Operators的介绍,包括元素运算符/Element Operators.集合方法/Aggregation.量词/Quantifiers Methods.元素运算符从一个sequ ...
- LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayIndex”
我就不屁话,能一张图就解决的就不说话了 2015-03-28 14:53:24,440 [10] ERROR log - System.NotSupportedException: LINQ to E ...
随机推荐
- c++ map删除元素
typedef std::map<std::string,float> StringFloatMap; StringFloatMap col1; StringFloatMap::itera ...
- COJ1013 : WZJ的数据结构(十三)
这道题有这样一个解法: 首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr ...
- mysql中INSTR函数的用法
mysql中INSTR函数的用法 INSTR(字段名, 字符串) 这个函数返回字符串在某一个字段的内容中的位置, 没有找到字符串返回0,否则返回位置(从1开始) SELECT * FROM tblTo ...
- CentOS 下安装python 之MySQLdb
yum -y install mysql-devwget http://downloads.sourceforge.net/project/mysql-python/mysql-python-test ...
- DTD约束的校验工具安装及检验(Iexmltls工具)
通过打开我们写的dtd约束文档,我们可以看到,在我们不按规定的格式打开xml时并不能检验出错误.此时我们可以借助软件来帮助我们校验. Iexmltls是一个在IE浏览器下安装的用于检验xml约束是否正 ...
- NVlink
Nvidia's Pascal to use stacked memory, proprietary NVLink interconnect by Scott Wasson — 6:50 PM on ...
- centos7 安装及配置
第一步 下载centoshttps://www.centos.org/download/CentOS-7.0-1406-x86_64-DVD.iso:这个镜像(DVD image)包括了那些可以用安装 ...
- bash shell命令行选项与修传入参数处理
在编写shell程序时经常需要处理命令行参数,本文描述在bash下的命令行处理方式.选项与参数:如下命令行: ./test.sh -f config.conf -v --prefix=/home -f ...
- Navicat for MySQL数据库管理工具
官网下载地址:http://www.navicat.com/download/navicat-for-mysql //如图所示成功建立连接 Host Nmae/Ip Adress:localhost ...
- PHP file_get_contents函数读取远程数据超时的解决方法
PHP file_get_contents函数读取远程数据超时的解决方法 投稿:junjie 字体:[增加 减小] 类型:转载 这篇文章主要介绍了PHP file_get_contents函数读取 ...