使用 POCO 实体(实体框架)

使用实体框架 ,可以将自定义数据类与数据模型一起使用,而无需对数据类本身进行任何修改。 这意味着可以将“纯旧式”CLR 对象 (POCO)(例如,现有的域对象)与数据模型一起使用。 这些 POCO 数据类(也称为“永久性未知对象”)映射到数据模型中定义的实体,它们支持与实体数据模型 工具生成的实体类型相同的大多数查询、插入、更新和删除行为。

映射要求

若要将 POCO 实体与数据模型一起使用,实体类型的名称必须与自定义数据类的名称相同,且实体类型的每个属性必须映射到自定义数据类的公共属性。 类型名称必须与映射的每个属性等效。 有关如何在概念模型中修改实体的信息,请参见How to: Create and Modify Entity Types

Dd456853.note(zh-cn,VS.100).gif注意:
如果对自定义数据类应用了任何映射特性(包括程序集级别的 EdmSchemaAttribute),则不支持映射 POCO 实体。

可以使用 POCO 模板从概念模型中生成持久性未知实体类型。 该模板未包含在 Visual Studio 中,但可从 Visual Studio 库(可能为英文网页)中下载。

代理对象创建

当 POCO 类中发生更改时,如果希望实体框架 跟踪这些更改并支持相关对象的延迟加载,则 POCO 类必须符合创建 POCO 代理的要求(实体框架)主题中描述的要求。

为 POCO 实体启用代理对象创建后,在对对象图和对象的属性值进行更改时,实体框架 将自动跟踪所做的更改。 有关在使用代理和不适用代理时的更改跟踪选项的信息,请参见跟踪 POCO 实体中的更改(实体框架)

可以混合使用 POCO 实体和代理实体对象。 若要禁止创建代理对象,请在 ObjectContext 上的 ContextOptions 属性返回的 ObjectContextOptions 的实例上,将 ProxyCreationEnabled 属性的值设置为 false

' Disable proxy object creation. 
context.ContextOptions.ProxyCreationEnabled = False
// Disable proxy object creation.
context.ContextOptions.ProxyCreationEnabled = false;

有关更多信息,请参见如何:创建带有代理的 POCO 实体(实体框架)

序列化 POCO 代理

Windows Communication Foundation (WCF) 不能对代理进行直接序列化或反序列化,因为 DataContractSerializer 只能序列化和反序列化已知类型,而代理类型是未知类型。 如果需要序列化 POCO 实体,请禁用代理创建或使用 ProxyDataContractResolver 类将代理对象作为原始 POCO 实体进行序列化。 若要禁用代理创建,请将 ProxyCreationEnabled 属性设置为 false

在序列化过程中,ProxyDataContractResolver 类可将代理类型映射到 POCO 类型。 若要指示 DataContractSerializer 在服务操作中使用 ProxyDataContractResolver 类,请定义一个特性类(此类将被应用于服务操作),在内部使用 ProxyDataContractResolver 将代理类型映射到纯 POCO 类型。 将此特性类与作为 WCF 应用程序中服务协定的一部分的方法相关联。

客户端将接收实际的 POCO 实体并对其进行反序列化。 这些类不具有代理对象的延迟加载和更改跟踪功能。 若要跨多个层跟踪这些实体的更改,请使用自跟踪实体。 自跟踪实体是实体框架 上不具有依赖项的 POCO 实体,它包含自己的更改跟踪逻辑。 有关更多信息,请参见演练:序列化自跟踪实体(实体框架)

有关更多信息,请参见演练:使用 WCF 序列化 POCO 代理(实体框架)

使用二进制序列化可以序列化和反序列化代理对象。 但是,当跨 AppDomain 边界对对象图进行序列化时,必须确保目标环境中存在代理类型定义。 如果这些类型不存在,则反序列化将会失败。 若要确保该类型存在,请使用 CreateProxyTypes

Dd456853.note(zh-cn,VS.100).gif注意:
即使创建了代理类型的对象,但它也不具有代理的延迟加载和更改跟踪功能。

使用二进制序列化和数据协定序列化,可以将相关对象与主对象一起序列化。 延迟加载会对访问的每个关系导航属性执行查询,并且二进制和 WCF 数据协定序列化程序都会访问所有关系导航属性。 这可能会导致要在序列化期间执行许多意外查询。 如果没有禁用代理类型生成(这将禁用延迟加载),请显式禁用延迟加载,如下面的示例所示。

' Disable lazy loading. 
context.ContextOptions.LazyLoadingEnabled = False
// Disable lazy loading.
context.ContextOptions.LazyLoadingEnabled = false;

有关更多信息,请参见序列化对象(实体框架)

特定于代理的 API 的摘要

下面的 API 与使用 POCO 代理相关:

成员 说明

CreateObject

如果 POCO 类符合创建 POCO 代理的要求(实体框架)主题中描述的要求,且 ProxyCreationEnabled 设置为 true,则将创建新的 POCO 代理对象,否则将创建泛型参数类型的对象。 此方法的泛型参数可以为任何具体引用类型(不支持抽象类、接口和值类型)。 如果泛型类型是没有映射到概念模型的 CLR 类型,或者是不符合代理创建要求的类型,则该方法将尝试使用所传递类型的任何无参数构造函数来创建和返回该类型的新实例。 除了 ObjectContext 上的 CreateObject 之外,还可以使用 ObjectSet 上的 CreateObjectCreateObject 方法。 有关更多信息,请参见如何:创建带有代理的 POCO 实体(实体框架)

此方法不会将创建的对象添加到对象上下文。 若要将对象添加到上下文,需要使用创建、添加、修改和删除对象(实体框架)主题中描述的方法。

ProxyCreationEnabled

将此标志设置为 true,实体框架将尝试为 POCO 实体创建代理。 默认情况下,ProxyCreationEnabled 标志设置为 true

GetObjectType

System.Data.Objects.ObjectContext.GetObjectType(System.Type) 是一个静态方法,如果作为参数传递的是代理类型,将返回从中派生指定代理的 POCO 类型。 如果传递的是非代理类型,则此方法将返回相同的类型。

CreateProxyTypes

根据 ObjectContext 中加载的元数据,为指定的 POCO 类型创建一组代理类型。 此方法不会对所创建代理类型的对象进行实例化。 例如,下面的代码将为 CustomerOrder POCO 类创建代理:context.CreateProxyTypes(new Type[] { typeof(Customer), typeof(Order) });

在从数据源加载对象或使用 CreateObject 创建新对象时,实体框架将在运行时为 POCO 类创建代理类型。 但有时您可能需要事先创建代理类型。 例如,当跨 AppDomain 边界对对象图进行序列化时,您可能需要确保目标环境中实际存在该代理类型。 如果这些类型不存在,则反序列化将会失败。

GetKnownProxyTypes

GetKnownProxyTypes 是一个静态方法,它返回一个枚举,其中包含迄今为止在 AppDomain 中创建的所有代理类型。 在序列化方案中,该方法可以用于获取目标环境应已包含且序列化程序应识别的所有类型。

本节内容

创建 POCO 代理的要求(实体框架)

加载相关 POCO 实体(实体框架)

跟踪 POCO 实体中的更改(实体框架)

如何:定义 POCO 实体(实体框架)

如何:定义自定义对象上下文(实体框架)

如何:自定义建模和映射文件以使用自定义对象(实体框架)

如何:定义自定义对象上下文(实体框架)

如何:创建带有代理的 POCO 实体(实体框架)

如何:显式加载 POCO 实体(实体框架)

如何:检测 POCO 实体中的更改

如何:更改 POCO 实体之间的关系(实体框架)

以下是来自 ADO.NET(可能为英文网页)的有关 POCO 的博客文章系列。

POCO

Entity Framework 4 中的 POCO - 第 2 部分

Entity Framework 4 中的 POCO - 第 3 部分

另请参见

概念

自定义对象(实体框架)
定义和管理关系(实体框架)