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

时间:2012-02-29 15:03:03

标签: c# entity-framework

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

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

我的代码在此行上失败了。我的所有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;

6 个答案:

答案 0 :(得分:45)

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

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

修改

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

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

答案 1 :(得分:6)

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

_dbContext.Configuration.ProxyCreationEnabled = false;

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

答案 2 :(得分:2)

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

在EF 4.1中,您可以使用NoTracking合并选项。每次通话都会进入数据库。

答案 3 :(得分:1)

在EF 6.1.3中,您可以使用

获得正确的类型
-misc-fixed-medium-r-semicondensed--0-0-75-75-c-0-iso8859-1 
-misc-fixed-medium-r-semicondensed--13-100-100-100-c-60-iso8‌​859-1 
-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso885‌​9-1
  

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

来自MSDN

答案 4 :(得分:0)

一个简单的解决方案是您缺少一些必须包含的对象,并且在获取值之前也要执行此操作

_dbContext.Configuration.ProxyCreationEnabled = false;

答案 5 :(得分:0)

就我而言,此问题已通过将Lazy Loading Enabled设置为false来解决。

  1. 打开.edmx(图)
  2. 按F4键显示属性
  3. Lazy Loading Enabled设置为false
  4. 保存并重建