为什么EF返回代理类而不是实际实体?

当我想要实际的实体类时,我遇到了entity framework返回代理的问题。 我第一次运行我的代码时,一切都正常运行(没有代理),但每次迭代之后,我的一个DbSets总是返回代理而不是实际类型。

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

我的代码在这一行失败了。 我的所有POCO都设置了Table属性,但因为它返回了一个代理类,所以没有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; 

您可以将ObjectContext.ContextOptions.ProxyCreationEnabled设置为false。 这将阻止您使用一些EFs花哨的function,如延迟加载,我相信更改跟踪。

就您的应用而言,它应该能够像代表它们所代表的类型一样对待代理。 你有特定的问题吗?

编辑

我们有一些代码需要POCO类型而不是代理类型,我们执行以下操作来检测当前类型是否是代理。

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

要在Entity Framework 5中关闭代理创建,您可以使用以下方法,

 _dbContext.Configuration.ProxyCreationEnabled = false; 

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

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

在EF 4.1中,您可以使用NoTracking Merge选项。 这将转到每次通话的数据库。

在EF 6.1.3中,您可以使用正确的类型

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

请注意,如果传递给GetObjectType的类型是不是代理类型的实体类型的实例,则仍会返回实体类型。 这意味着您始终可以使用此方法获取实际实体类型,而无需进行任何其他检查以查看该类型是否为代理类型。

来自MSDN