EntityFramework学习Word文档格式.docx
《EntityFramework学习Word文档格式.docx》由会员分享,可在线阅读,更多相关《EntityFramework学习Word文档格式.docx(83页珍藏版)》请在冰点文库上搜索。
∙
应用程序可以通过更加以应用程序为中心的概念性模型(包括具有继承性、复杂成员和关系的类型)来工作。
应用程序不再对特定的数据引擎或存储架构具有硬编码依赖性。
可以在不更改应用程序代码的情况下更改概念性模型与特定于存储的架构之间的映射。
开发人员可以使用可映射到各种存储架构(可能在不同的数据库管理系统中实现)的一致的应用程序对象模型。
多个概念性模型可以映射到同一个存储架构。
语言集成查询支持可为查询提供针对概念性模型的编译时语法验证。
实体框架EntityFramework是ADO.NET中的一组支持开发面向数据的软件应用程序的技术。
在EF中的实体数据模型(EDM)由以下三种模型和具有相应文件扩展名的映射文件进行定义。
概念架构定义语言文件(.csdl)--定义概念模型。
存储架构定义语言文件(.ssdl)--定义存储模型(又称逻辑模型)。
映射规范语言文件(.msl)--定义存储模型与概念模型之间的映射。
实体框架使用这些基于XML的模型和映射文件将对概念模型中的实体和关系的创建、读取、更新和删除操作转换为数据源中的等效操作。
EDM甚至支持将概念模型中的实体映射到数据源中的存储过程。
它提供以下方式用于查询EDM并返回对象:
LINQtoEntities--提供语言集成查询(LINQ)支持用于查询在概念模型中定义的实体类型。
EntitySQL--与存储无关的SQL方言,直接使用概念模型中的实体并支持诸如继承和关系等EDM功能。
查询生成器方法--可以使用LINQ风格的查询方法构造EntitySQL查询。
下图演示用于访问数据的实体框架体系结构:
下面,来学习EF的基本使用方法。
软件环境:
:
VisualStudio2008+SP1
SQLServer2005/2008
首先,建立一个名为“EFProject”的解决方案,然后添加一个名为“EFModel”的类库项目。
如下图所示。
接着,在EFModel项目中,添加“ADO.NETEntityDataModel”项目,如下图所示:
名称取为“NorthWindEF.edmx”,然后点击“添加”。
然后,在后面的步骤中,数据库选择“NorthWind”后,在选择影射对象是,把表、试图、存储过程全部都选上,其他的均保存默认的即可。
最终生成的结果如下图所示。
好了,数据模型生成完毕。
最后,谈谈我认为的一些缺点:
Edmx包含了所有对象的csdl,ssdl,msl文件,过于庞大,如果要手动修改这个文件,一不小心,眼睛看花了,就改错了。
(和数据集一样的毛病)。
目前EF支持表、试图、存储过程,其他的对象不支持,而且对使用存储过程有很多限制(目前有EFExtension提供了更多对象的支持)。
除了MSSQLServer可直接提供这种可视化的设计界面外,其他的数据库目前还没有提供可视化设计界面(但可以自己来实现,后面介绍)。
性能问题。
(网上看到有说比ADO.Net慢700百,又有人说比ADO.net快的,具体情况我还没测试过,但我觉得像这个些类型的框架,性能肯定是比上原生态的ADO.net慢)
好了,接下来,学习以下简单的各种操作。
EntityFramework学习初级篇2--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍
本节,简单的介绍EF中的ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager这个几个比较重要的类,它们都位于System.Data.Entity.dll下的System.Data.Objects命名空间下。
在后续的章节中,我们经常会用到它们的某些方法,以便完成我们的某些操作或目的。
本节,简单的说明一下以后我们可能会用到的各个类的方法,以方便我们后续的学习。
ObjectContext封装.NETFramework和数据库之间的连接。
此类用作“创建”、“读取”、“更新”和“删除”操作的网关。
ObjectContext类为主类,用于与作为对象(这些对象为EDM中定义的实体类型的实例)的数据进行交互。
ObjectContext类的实例封装以下内容:
●
到数据库的连接,以EntityConnection对象的形式封装。
描述该模型的元数据,以MetadataWorkspace对象的形式封装。
用于管理缓存中持久保存的对象的ObjectStateManager对象。
ObjectContext类的成员方法以说明如下所示:
AcceptAllChanges()
接受所有对该实体对象的更改
AddObject(string,object)
将实体对象添加到制定的实体容器中
ApplyPropertyChanges(string,object)
将以指派的实体对象属性的更改应用到容器中对应的原对象。
Attach(System.Data.Objects.DataClasses.IEntityWithKeyentity)
将带主键的实体对象附加到默认的容器中
Attach(string,object)
将实体对象附加到指定的实体容器中
CreateEntityKey(string,object)
给指定的实体对象创建实体主键或如果已存在实体主键,则直接返回该实体的主键
CreateQuery<
T>
(string,paramsObjectParameter[])
从给定的查询字符串创建ObjectQuery对象。
DeleteObject(object)
删除指定的实体对象
Detach(object)
移除指定的实体对象
ExecuteFunction<
TElement>
对默认容器执行给定的函数。
GetObjectByKey(System.Data.EntityKeykey)
通过主键KEY从ObjectStateManager中检索对象(如果存在);
否则从存储区中检索。
Refresh(System.Data.Objects.RefreshModerefreshMode,objectentity)
按指定持久更新模式,使用指定实体的存储区数据更新ObjectStateManager。
。
Refresh(System.Data.Objects.RefreshModerefreshMode,System.Collections.IEnumerablecollection)
按指定持久处理模式,使用指定实体集的存储区数据更新ObjectStateManager。
SaveChanges(bool)
将所有更新持久保存到存储区中。
参数是客户端事务支持所需的参数。
参数为true则在更新后自动将更改应用到ObjectStateManager中的实体。
如果为false,则在更新后还需要调用AcceptAllChanges()以便更新ObjectStateManager中的实体。
SaveChanges()
将所有更新持久保存到存储区中
TryGetObjectByKey(System.Data.EntityKey,outobject)
尝试从指定实体主键返回该实体
以上各个方法的具体用法,将在后面介绍。
接着,再看看有用的类ObjectQuery。
ObjectQuery有个有用的方法ToTraceString(),这个方法用于追踪所执行的SQL语句,通过此方法我们可以获取所执行的SQL语句,以便我们查看、分析具体执行的SQL语句。
(类似Nhibernate配置文件中的showsql节)
再了解一下ObjectStateEntry。
ObjectStateEntry维护实体实例或关系实例的状态(已添加、已删除、已分离、已修改或未更改)、键值和原始值。
还管理已修改属性的列表。
其包含一下方法:
AcceptChanges
接受当前值作为原始值,并将实体标记为Unchanged()。
Delete
将实体标记为Deleted()。
如果实体处于Added()()()状态,它将为Detached()。
GetModifiedProperties
返回标记为Modified()的属性名称。
SetModified
将状态设置为Modified()。
SetModifiedProperty
将指定的属性标记为Modified()。
接着,再看看ObjectStateManager。
ObjectStateManager用于维护对象映射、对象状态/标识管理以及实体实例或关系实例的持久性。
GetObjectStateEntries
获取给定EntityState的ObjectStateEntry集合。
GetObjectStateEntry
获取给定的EntityKey对应的ObjectStateEntry
现在,几个重要的类简单介绍完毕。
后面,我们将具体学习它们的使用。
EntityFramework学习初级篇3--LINQTOEntities
LINQ技术(即LINQtoEntities)使开发人员能够通过使用LINQ表达式和LINQ标准查询运算符,直接从开发环境中针对实体框架对象上下文创建灵活的强类型查询。
LINQtoEntities查询使用对象服务基础结构。
ObjectContext类是作为CLR对象与实体数据模型进行交互的主要类。
开发人员通过ObjectContext构造泛型ObjectQuery实例。
ObjectQuery泛型类表示一个查询,此查询返回一个由类型化实体组成的实例或集合。
返回的实体对象可供更新并位于对象上下文中。
以下是创建和执行LINQtoEntities查询的过程:
1.
从ObjectContext构造ObjectQuery实例。
2.
通过使用ObjectQuery实例在C#或VisualBasic中编写LINQtoEntities查询。
3.
将LINQ标准查询运算符和表达式将转换为命令目录树。
4.
对数据源执行命令目录树表示形式的查询。
执行过程中在数据源上引发的任何异常都将直接向上传递到客户端。
5.
将查询结果返回到客户端。
一、LinqToEntities简单查询
下面将介绍简单的LinqToEntities查询,相关的查询语法可以使用基于表达式或基于方法的语法。
本节使用的TestDriver.Net配合Nunit2.4进行测试。
1,
投影
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Data.Objects;
usingNUnit.Framework;
namespaceNorthWindModel
{
[TestFixture]
publicclassTestEFModel
{
[Test]
publicvoidSelect()
using(varedm=newNorthwindEntities())
//基于表达式的查询语法
ObjectQuery<
Customers>
customers=edm.Customers;
IQueryable<
cust1=fromcincustomers
selectc;
Assert.Greater(cust1.Count(),0);
//使用ObjectQuery类的ToTraceString()方法显示查询SQL语句
Console.WriteLine(customers.ToTraceString());
}
}
输出:
SELECT
[Extent1].[CustomerID]AS[CustomerID],
[Extent1].[CompanyName]AS[CompanyName],
[Extent1].[ContactName]AS[ContactName],
[Extent1].[ContactTitle]AS[ContactTitle],
[Extent1].[Address]AS[Address],
[Extent1].[City]AS[City],
[Extent1].[Region]AS[Region],
[Extent1].[PostalCode]AS[PostalCode],
[Extent1].[Country]AS[Country],
[Extent1].[Phone]AS[Phone],
[Extent1].[Fax]AS[Fax]
FROM[dbo].[Customers]AS[Extent1]
1passed,0failed,0skipped,took11.00seconds(NUnit2.4).
在上面的输出内容中,可以看到使用了ToTraceString()方法来输出具体的SQL语句。
同时Nunit也输出相关的测试情况,请注意查询所花费的时间,以便我们进行查询速度的分析比较。
2,
条件限制
using(varedm=newNorthwindEntities())
wherec.CustomerID=="
ALFKI"
Assert.AreEqual(cust1.Count(),1);
foreach(varcincust1)
Console.WriteLine("
CustomerID={0}"
c.CustomerID);
//基于方法的查询语法
varcust2=edm.Customers.Where(c=>
c.CustomerID=="
);
Assert.AreEqual(cust2.Count(),1);
foreach(varcincust2)
3,
排序和分页
在使用Skip和Take方法实现分页时,必须先对数据进行排序,否则将会抛异常。
//基于表达式的查询语法
cust10=(fromcincustomers
orderbyc.CustomerID
selectc).Skip(0).Take(10);
Assert.AreEqual(cust10.Count(),10);
foreach(varcincust10)
//基于方法的查询语法
varcust=edm.Customers.OrderBy(c=>
c.CustomerID).Skip(0).Take(10);
Assert.AreEqual(cust.Count(),10);
foreach(varcincust)
4,
聚合
可使用的聚合运算符有Average、Count、Max、Min和Sum。
varmaxuprice=edm.Products.Max(p=>
p.UnitPrice);
Console.WriteLine(maxuprice.Value);
5,
连接
可以的连接有Join和GroupJoin方法。
GroupJoin组联接等效于左外部联接,它返回第一个(左侧)数据源的每个元素(即使其他数据源中没有关联元素)。
varquery=fromdinedm.Order_Details
joinorderinedm.Orders
ond.OrderIDequalsorder.OrderID
selectnew
OrderId=order.OrderID,
ProductId=d.ProductID,
UnitPrice=d.UnitPrice
};
foreach(varqinquery)
{0},{1},{2}"
q.OrderId,q.ProductId,q.UnitPrice);
其他一些方法等就不多说了,和LinqtoSQL基本上是一样的。
二、LINQtoEntities查询注意事项
排序信息丢失
如果在排序操作之后执行了任何其他操作,则不能保证这些附加操作中会保留排序结果。
这些操作包括Select和Where等。
另外,采用表达式作为输入参数的First和FirstOrDefault方法不保留顺序。
如下代码:
并不能达到反序排序的效果
cc=edm.Customers.OrderByDescending(c=>
c.CustomerID).Where(c=>
c.Region!
=null).Select(c=>
c);
foreach(varcincc)
Console.WriteLine(c.CustomerID);
不支持无符号整数
由于实体框架不支持无符号整数,因此不支持在LINQtoEntities查询中指定无符号整数类型。
如果指定无符号整数,则在查询表达式转换过程中会引发NotSupportedException异常,并显示无法创建类型为“结束类型”的常量值。
此上下文仅支持基元类型(“例如Int32、String和Guid”)。
如下将会报异常的代码: