如何搭建.NET Entity Framework分布式应用系统框架
1个回答
展开全部
一、 前言
ADO.NET Entity Framework(以下简称EF)是微软推出的一套O/RM框架,如果用过Linq To SQL的人会比较容易理解,因为Linq To SQL是微软在.net FrameWork 3.0时推出的一套轻量级的O/RM框架,但是只支持SQL Server一种数据库。至.net FrameWork 3.5 sp1时,才推出Entity FrameWork,可以通过实现不同的Provider来支持不同的数据库(当然微软还是只内置SQL Server的Provider,其它数据库的Provider么,需要第三方开发)。EF加上linq,这是.net开发上的一个巨大进步,.net程序员以对象方式操作数据,以类sql语法在程序里查询数据,大大减少了繁琐的构造SQL语句的工作,可以更加专注于编写业务逻辑代码。但是在多层架构的分布式应用系统中,实体对象通过远程序列化到客户端时,这些实体会与其数据上下文(也就是实体容器)分离,在客户端无法对实体直接进行查询以及CUD(Create,Update,Delete)操作,下面以SQL Server为数据库,Remoting+Entity Framework3.5作为数据服务层,WinForm作为客户端,讲述一下如何使用EF框架搭建多层分布式应用系统。
二、 预备知识
1. Linq To SQL或者 EF方面的基础知识。此处不作赘述。
2. 分布式应用系统方面的基础知识。所谓分布式应用系统,对于.net而言,就是使用了诸如COM+,.net Remoting,XML WEB Service,WCF,MSMQ等远程调用技术的多层架构应用系统,所以需要对上述技术有一定了解。此处不作赘述。
3. 面向对象编程的一些基础知识。此处不作赘述。
三、 技术分析
1. 通过远程客户端传输过来的实体,都是处于分离状态(EntityState属性值为Detached),所以在多层应用程序中的服务端实现实体的更新或删除时,关键是如何把实体附加回实体容器中。MSDN上关于对分离实体的查询和CUD操作描述如下:
1) 附加对象(实体框架)
在实体框架的某个对象上下文内执行查询时,返回的对象会自动附加到该对象上下文。还可以将从源而不是从查询获得的对象附加到对象上下文。您可以附加以前分离的对象、由 NoTracking 查询返回的对象或从对象上下文的外部获取的对象。还可以附加存储在 ASP.NET 应用程序的视图状态中的对象或从远程方法调用或 Web 服务返回的对象。
使用下列方法之一将对象附加到对象上下文:
· 调用 ObjectContext 上的 AddObject 将对象附加到对象上下文。当对象为数据源中尚不存在的新对象时采用此方法。
· 调用 ObjectContext上的 Attach 将对象附加到对象上下文。当对象已存在于数据源中但当前尚未附加到上下文时采用此方法。有关更多信息,请参见如何:附加相关对象(实体框架)。
· 调用 ObjectContext的 AttachTo,以将对象附加到对象上下文中的特定实体集。如果对象具有 null(在 Visual Basic 中为 Nothing)EntityKey 值,也可以执行此操作。
· 调用 ObjectContext上的 ApplyPropertyChanges。当对象已存在于数据源中,并且分离的对象具有您希望保存的属性更新时采用此方法。如果简单地附加该对象,则属性更改将丢失。有关更多信息,请参见如何:应用对已分离对象的更改(实体框架)。
2) 应用对已分离对象的更改(实体框架)示例代码
privatestaticvoid ApplyItemUpdates(SalesOrderDetail updatedItem)
{
// Define an ObjectStateEntry and EntityKey for the current object.
EntityKey key;
object originalItem;
using (AdventureWorksEntities advWorksContext =
newAdventureWorksEntities())
{
try
{
// Create the detached object's entity key.
key = advWorksContext.CreateEntityKey("SalesOrderDetail", updatedItem);
// Get the original item based on the entity key from the context
// or from the database.
if (advWorksContext.TryGetObjectByKey(key, out originalItem))
{
// Call the ApplyPropertyChanges method to apply changes
// from the updated item to the original version.
advWorksContext.ApplyPropertyChanges(
key.EntitySetName, updatedItem);
}
advWorksContext.SaveChanges();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}
}
2. 实现动态条件查询。在本地环境中,对于Linq,我们可以通过动态构造Lambda表达式树来实现动态条件查询,但是在远程环境中,Lamdba表达式不支持远程序列化传输,只能通过ObjectContext的CreateQuery方法实现,但幸好微软后来又提供了一个LINQ动态查询扩展库Dynamic.cs,使用起来更方便,于是采用它实现。
3. EF中核心抽象类是ObjectContext,实体容器都从它派生,实体容器上的CUD方法其实都是通过调用ObjectContext的CUD操作方法实现的。
1) AddObject(string,object):表示添加实体object到实体容器,只要实体的EntityKey值为空,无论是否Detached状态均可以通过此方法实现添加操作。
2) ApplyPropertyChanges(string,object)表示把分离状态的实体object上的所作的修改更新回容器中已存在的对应的实体,执行条件有两个:①实体处于分离状态,②实体容器中存在主键值与其相同的且为Unchanged状态的实体,所以,当我们需要更新一个Detached状态的实体时,可以先把一个具有原始值的相同键值的实体附加回容器中,或者直接执行一下查询,从数据库中取出该实体。
3) DeleteObject(object)表示从实体容器中删除一个实体,执行条件是该实体存在于实体容器中,所以删除一个Detach状态的实体之前,需要把它通过Attach方法附加回实体容器中。
4. 实体对象也是基于抽象类EntityObject派生的,由此我们完全可以用ContextObject和EntityObject实现服务端对实体的查询和CUD方法,其实现子类在运行时由客户端注入,从而使服务端和数据库实现松耦合。
5. 下图是MSDN上关于在数据访问层中使用 LINQ to SQL 的 n 层应用程序的基本体系结构图,其实EF的结构也是一样的,不过是把DataContext换成ObjectContext。
ADO.NET Entity Framework(以下简称EF)是微软推出的一套O/RM框架,如果用过Linq To SQL的人会比较容易理解,因为Linq To SQL是微软在.net FrameWork 3.0时推出的一套轻量级的O/RM框架,但是只支持SQL Server一种数据库。至.net FrameWork 3.5 sp1时,才推出Entity FrameWork,可以通过实现不同的Provider来支持不同的数据库(当然微软还是只内置SQL Server的Provider,其它数据库的Provider么,需要第三方开发)。EF加上linq,这是.net开发上的一个巨大进步,.net程序员以对象方式操作数据,以类sql语法在程序里查询数据,大大减少了繁琐的构造SQL语句的工作,可以更加专注于编写业务逻辑代码。但是在多层架构的分布式应用系统中,实体对象通过远程序列化到客户端时,这些实体会与其数据上下文(也就是实体容器)分离,在客户端无法对实体直接进行查询以及CUD(Create,Update,Delete)操作,下面以SQL Server为数据库,Remoting+Entity Framework3.5作为数据服务层,WinForm作为客户端,讲述一下如何使用EF框架搭建多层分布式应用系统。
二、 预备知识
1. Linq To SQL或者 EF方面的基础知识。此处不作赘述。
2. 分布式应用系统方面的基础知识。所谓分布式应用系统,对于.net而言,就是使用了诸如COM+,.net Remoting,XML WEB Service,WCF,MSMQ等远程调用技术的多层架构应用系统,所以需要对上述技术有一定了解。此处不作赘述。
3. 面向对象编程的一些基础知识。此处不作赘述。
三、 技术分析
1. 通过远程客户端传输过来的实体,都是处于分离状态(EntityState属性值为Detached),所以在多层应用程序中的服务端实现实体的更新或删除时,关键是如何把实体附加回实体容器中。MSDN上关于对分离实体的查询和CUD操作描述如下:
1) 附加对象(实体框架)
在实体框架的某个对象上下文内执行查询时,返回的对象会自动附加到该对象上下文。还可以将从源而不是从查询获得的对象附加到对象上下文。您可以附加以前分离的对象、由 NoTracking 查询返回的对象或从对象上下文的外部获取的对象。还可以附加存储在 ASP.NET 应用程序的视图状态中的对象或从远程方法调用或 Web 服务返回的对象。
使用下列方法之一将对象附加到对象上下文:
· 调用 ObjectContext 上的 AddObject 将对象附加到对象上下文。当对象为数据源中尚不存在的新对象时采用此方法。
· 调用 ObjectContext上的 Attach 将对象附加到对象上下文。当对象已存在于数据源中但当前尚未附加到上下文时采用此方法。有关更多信息,请参见如何:附加相关对象(实体框架)。
· 调用 ObjectContext的 AttachTo,以将对象附加到对象上下文中的特定实体集。如果对象具有 null(在 Visual Basic 中为 Nothing)EntityKey 值,也可以执行此操作。
· 调用 ObjectContext上的 ApplyPropertyChanges。当对象已存在于数据源中,并且分离的对象具有您希望保存的属性更新时采用此方法。如果简单地附加该对象,则属性更改将丢失。有关更多信息,请参见如何:应用对已分离对象的更改(实体框架)。
2) 应用对已分离对象的更改(实体框架)示例代码
privatestaticvoid ApplyItemUpdates(SalesOrderDetail updatedItem)
{
// Define an ObjectStateEntry and EntityKey for the current object.
EntityKey key;
object originalItem;
using (AdventureWorksEntities advWorksContext =
newAdventureWorksEntities())
{
try
{
// Create the detached object's entity key.
key = advWorksContext.CreateEntityKey("SalesOrderDetail", updatedItem);
// Get the original item based on the entity key from the context
// or from the database.
if (advWorksContext.TryGetObjectByKey(key, out originalItem))
{
// Call the ApplyPropertyChanges method to apply changes
// from the updated item to the original version.
advWorksContext.ApplyPropertyChanges(
key.EntitySetName, updatedItem);
}
advWorksContext.SaveChanges();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}
}
2. 实现动态条件查询。在本地环境中,对于Linq,我们可以通过动态构造Lambda表达式树来实现动态条件查询,但是在远程环境中,Lamdba表达式不支持远程序列化传输,只能通过ObjectContext的CreateQuery方法实现,但幸好微软后来又提供了一个LINQ动态查询扩展库Dynamic.cs,使用起来更方便,于是采用它实现。
3. EF中核心抽象类是ObjectContext,实体容器都从它派生,实体容器上的CUD方法其实都是通过调用ObjectContext的CUD操作方法实现的。
1) AddObject(string,object):表示添加实体object到实体容器,只要实体的EntityKey值为空,无论是否Detached状态均可以通过此方法实现添加操作。
2) ApplyPropertyChanges(string,object)表示把分离状态的实体object上的所作的修改更新回容器中已存在的对应的实体,执行条件有两个:①实体处于分离状态,②实体容器中存在主键值与其相同的且为Unchanged状态的实体,所以,当我们需要更新一个Detached状态的实体时,可以先把一个具有原始值的相同键值的实体附加回容器中,或者直接执行一下查询,从数据库中取出该实体。
3) DeleteObject(object)表示从实体容器中删除一个实体,执行条件是该实体存在于实体容器中,所以删除一个Detach状态的实体之前,需要把它通过Attach方法附加回实体容器中。
4. 实体对象也是基于抽象类EntityObject派生的,由此我们完全可以用ContextObject和EntityObject实现服务端对实体的查询和CUD方法,其实现子类在运行时由客户端注入,从而使服务端和数据库实现松耦合。
5. 下图是MSDN上关于在数据访问层中使用 LINQ to SQL 的 n 层应用程序的基本体系结构图,其实EF的结构也是一样的,不过是把DataContext换成ObjectContext。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询