2012-02-29 84 views
23

当我想要实际的实体类时,我遇到了实体框架返回代理的问题。我第一次运行代码时,所有代码都可以正常运行(无代理),但每次迭代后,我的一个DbSets总是返回代理,而不是实际类型。为什么EF返回一个代理类而不是实际的实体?

我在每次迭代后处理上下文,所以我不明白为什么第一次通过它,每次都不行。

我的代码在这一行上失败。我所有的POCO都有Table属性集,但是因为它返回的是代理类,所以没有表属性。

TableAttribute attrib = (TableAttribute)attributes.Single(); 

DbContext中存在一些幕后静态魔法,它是在我销毁该对象后生活的吗?

我用移动我的对象到内存以下

MajorClasses = ctx.MajorClasses.ToArray(); 

我也试过

MajorClasses = ctx.MajorClasses.AsNoTracking().ToArray(); 

在我OnModelCreating,我有以下设置

base.Configuration.ProxyCreationEnabled = false; 
      base.Configuration.LazyLoadingEnabled = false; 

回答

38

您可以将ObjectContext.ContextOptions.ProxyCreationEnabled设置为false。这会阻止你使用一些EFs的花式功能,例如延迟加载,我相信改变跟踪。

就你的应用程序而言,它应该能够像代表它们的类型一样对待代理。你有什么具体问题吗?

编辑

我们有需要的POCO类型,而不是代理类型一些代码,我们下面来检测,如果当前类型是代理。

if (entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies") 
{ 
    entityType = entityType.BaseType; 
} 
+0

我在我的问题中增加了更多细节。我确实有这个设置集,没有我的应用程序不能像POCO那样处理代理。 – 2012-02-29 15:25:29

+0

它在更新的问题。我反映了从中获取属性的类。 – 2012-02-29 15:27:43

+0

@ MalcolmO'Hare我已经发布了我们用来从代理类型获取POCO类型的代码。 – cadrell0 2012-02-29 15:31:24

2

默认情况下,EF用途Change Tracking并使用所有实体的内存中缓存。使用EF时可以使用不同的合并选项。默认情况下,EF 4.1设置为AppendOnly Merge Option。据我所知,这意味着如果你已经查询过一个实体,随后的查询将从缓存中获取该实体(如果在数据库中没有检测到更改)。所以你可能会看到缓存实体回来。

在EF 4.1中,您可以使用NoTracking合并选项。这将进入每个电话的数据库。

+0

在我的节目的每一次迭代(其轮询数据库,当一个记录插入就在另一个数据库工作)我创建了一个新的环境和我的所有数据加载到内存中。当我所有的工作完成后,所有加载的数据+上下文都会被处理掉。如果我运行两次相同的导出,第二次运行一些记录将作为代理返回,这在第一次运行时不会发生。此外我现在使用4.3(升级,看看它是否解决了问题)。 – 2012-02-29 15:14:08

+0

是的,这听起来很奇怪,你会得到一个代理对象的基础上。不过,您可以设置为NoTracking来排除缓存。 – 2012-02-29 15:16:11

+1

@ MalcolmO'Hare代理是否是其他实体的虚拟属性?也许你只是看到EF延迟加载。如果您不使用(加载)设置为虚拟的实体,则它可能会显示为代理。 – 2012-02-29 15:16:57

6

要在实体框架5关闭代理的创作,你可以使用下面的,

_dbContext.Configuration.ProxyCreationEnabled = false; 

只需设置该属性使用上下文来提取数据之前一次。

1

在EF 6.1.3您可以使用

using (var context = new BloggingContext()) { 
    var blog = context.Blogs.Find(1); 
    var entityType = ObjectContext.GetObjectType(blog.GetType()); 
} 

注意得到正确的类型,如果传递给GetObjectType类型是实体类型的实例,它是不是一个代理类型,那么类型实体仍然返回。这意味着您可以始终使用此方法获取实际的实体类型,而无需其他任何检查来查看类型是否为代理类型。

MSDN

+2

他想要的是实际的实体,而不是它的类型。 – Tito 2017-07-17 08:22:01

相关问题