生成 N 层应用程序(实体框架)

实体框架 支持将实体对象序列化为支持在实体对象之间进行远程和基于消息的交换的格式,如与 Web 服务和 Windows Communication Foundation (WCF) 配合使用的格式。 可以通过使用二进制序列化、XML 序列化和 WCF 协定序列化对对象进行序列化,以便可以使用二进制流或基于消息的协议进行传输。 有关更多信息,请参见序列化对象(实体框架)。 还可以从消息或流接收对象,反序列化对象,并将对象附加到对象上下文。 有关更多信息,请参见附加和分离对象(实体框架)

通过 ADO.NET Data Services 可以提供对应用程序可使用的 XML 格式的实体数据的动态访问。 可以通过使用标准具象状态传输 (REST) HTTP 操作(如 GET、PUT 和 POST)访问这些实体数据。 有关更多信息,请参见 ADO.NET Data Services

下列注意事项适用于使用实体框架 的 Web 服务或 WCF 服务:

  • 使用二进制序列化和数据协定序列化,可以将相关对象与主对象一起序列化。 XML 序列化不会序列化相关对象。 当对实体进行序列化时,请禁用延迟加载。 延迟加载会对访问的每个关系导航属性执行查询,并且二进制和 WCF 数据协定序列化程序都会访问所有关系导航属性。 这可能会导致要在序列化期间执行许多意外查询。 有关更多信息,请参见序列化对象(实体框架)

  • 建议使用无状态服务。 应将服务设计为仅在请求或响应期间维护对象上下文。 消息交换模式应包含足够的信息,以便可以应用更改,而不必持久保存对象或重新查询数据源来检索原始对象。 例如,允许客户端更新对象的服务应要求更新的对象与原始对象一起返回。 这使 Web 服务可以将更改应用于原始对象,而不必从数据库检索原始对象或将其持久保存在内存中。 有关更多信息,请参见如何:应用对已分离对象的更改(实体框架)

  • 对象始终以 Detached 状态进行反序列化。 可能需要将对象附加或添加到 ObjectContext,也可能只需将属性更改应用于原始对象。 有关更多信息,请参见附加和分离对象(实体框架)

  • 在将对象和关系添加到上下文中后,您便可通过使用 ChangeObjectState 设置新状态(如 AddedModified)。

  • 必须手动管理并发操作和验证。

有关更多信息,请参见以下关于 N 层开发的文章:

Anti-Patterns(反模式)

N-Tier Application Patterns(N 层应用程序模式)

自跟踪实体

在实体框架 应用程序中,对象上下文负责跟踪对象中的更改。 但是,当需要操作其他层中的对象时,如果对象上下文不可用,则必须确定如何跟踪更改并将这些更改报告回对象上下文。 从 .NET Framework 版本 4 开始,自跟踪实体可帮助跟踪任意层中的更改。 自跟踪实体是从文本模板转换工具包 (T4) 模板中生成的一种实体,该模板生成的实体类型可以将更改记录到标量属性、复杂属性以及导航属性中。 有关更多信息,请参见使用自跟踪实体

若要在不使用自跟踪实体的情况下,在未将对象附加到对象上下文的层上跟踪更改,可使用下一节中的方法来帮助您更新上下文,以将相关更改持久保存到数据库中。

使用与 N 层应用程序开发相关的 API

使用以下方法可添加对象的整个图形,然后浏览该图形,将适当值应用到对象的属性,并对实体对象和关系设置正确的状态。

若要添加并附加实体,请使用以下方法:

成员 说明

System.Data.Objects.ObjectSet.AddObject(

System.Data.Objects.ObjectContext.AddObject(System.String,System.Object)

将一个对象及其相关对象添加到 ObjectContext,并将实体对象设置为 Added 状态。 在此状态下,实体对象不必具有唯一键值。 系统会将临时键值分配给键属性,并在您保存了对象后使用数据源生成的值更新临时键值。 在添加了对象之后,相应地更改实体对象的状态。

System.Data.Objects.ObjectSet.Attach(

System.Data.Objects.ObjectContext.Attach(System.Data.Objects.DataClasses.IEntityWithKey)

AttachTo

将一个对象添加到 ObjectContext,并将该对象设置为 Unchanged 状态。 在 Unchanged 状态下,实体框架 会将实体键值视为最终的值。 如果某个特定类型的多个实体具有相同键值,实体框架 将会引发异常。 若要避免获得异常,请使用 AddObject 方法附加已分离的对象,然后相应地更改状态。

若要更改标量值,请使用以下方法:

成员 说明

System.Data.Objects.ObjectSet.ApplyCurrentValues(

System.Data.Objects.ObjectContext.ApplyCurrentValues.String,

将标量值从提供的对象复制到 ObjectContext 中具有相同键的对象中。 任何与原始值不同的值都将标记为已修改。

如果您具有一个包含当前值的图形,并且希望应用原始值,请调用 ApplyOriginalValues 方法。

还可使用 ObjectStateEntryApplyCurrentValues 方法。

System.Data.Objects.ObjectSet.ApplyOriginalValues(

System.Data.Objects.ObjectContext.ApplyOriginalValues.String,

将标量值从提供的对象复制到 ObjectContext 中具有相同键的对象的原始值集中。 任何与当前值不同的值都将标记为已修改。

还可使用 ObjectStateEntryApplyOriginalValues 方法。

SetModifiedProperty

将单个属性设置为 Modified 状态。 当您知道哪些属性经过了修改时(而不是设置要修改的整个实体时)使用此属性。

GetUpdatableOriginalValues

获取表示与此 ObjectStateEntry 关联的对象的可更新原始值的 OriginalValueRecord 实例。 使用返回的 OriginalValueRecord 实例可单独读取或更新该对象的原始属性。

CurrentValues

获取表示与此 ObjectStateEntry 关联的对象的当前值的 CurrentValueRecord 实例。 使用返回的 CurrentValueRecord 实例可单独读取或更新该对象的当前属性。

若要更改实体和关系状态,请使用以下方法:

成员 说明

ChangeObjectState

将实体或关系更改为新状态(如 AddedModified)。 此更改可能会对某个实体参与的关系产生影响。 例如,将某个实体迁移到 Added 状态也会将任何未更改的关系迁移到 Added 状态。 同样,将某个实体标记为 Modified 也会将所有标量值标记为 Modified

还可使用 ObjectStateEntryChangeState 方法。

ChangeRelationshipState

将两个实体之间的现有关系更改为指定状态。 如果实体间无任何关系,则此方法将创建一种处于指定状态的新关系。 对于基于外键关联的关系,不支持此方法。 有关更多信息,请参见定义和管理关系(实体框架)

还可使用 ObjectStateEntryChangeState 方法。

ChangeState

根据 ObjectStateEntry 是对象还是关系,此方法的行为与 ChangeObjectStateChangeRelationshipState 的行为相同。

SetModifiedProperty

将单个属性设置为 Modified 状态。 当您知道哪些属性经过了修改时(而不是设置要修改的整个实体时)使用此方法。

若要将更改保存到数据源,请使用以下方法:

成员 说明

SaveChanges

将所有更改持久保存到数据源。

如果您想要在对象具体化期间获取或设置某些信息,或订阅某些事件,请使用 ObjectMaterialized 事件。

成员 说明

ObjectMaterialized

当使用数据源中的数据创建新的实体对象(作为查询或加载操作的一部分)时发生。 此事件是在已加载引用对象之后、加载集合之前引发的。 如果上下文中存在具有相同键值的对象,实体框架 将不会重新创建对象,并且不会引发此事件。

另请参见

概念

使用对象(实体框架)