尽管代理被禁用,实体框架会自动设置关系
Posted
技术标签:
【中文标题】尽管代理被禁用,实体框架会自动设置关系【英文标题】:Entity Framework automatically sets relationship although proxies are disabled 【发布时间】:2017-12-06 20:31:09 【问题描述】:我在理解 Entity Framework 如何为内存中的实体连接实体关系时遇到了一些麻烦。
要使用实体框架进行查询,我禁用了代理创建和延迟加载:
public static CoreContext GetReadCoreContext()
var context = GetCoreContext();
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
return context;
由于我在 ER 模型中有一些继承类型,并且我只想在继承类型是特定类型时才包含一些实体,因此我需要执行两个单独的查询。只有特定类型包含与本地化的关系。请注意,这只是为了说明为什么我必须进行两个单独的查询,并且不一定与我努力理解 Entity Framework 的机制有关。
首先查询通用部分,不依赖于具体类型:
var myGuid = Guid.Parse("6a81de0b-ce4b-44dc-a693-ca4e13e7d2ab");
using (var ctx = ContextFactory.GetReadCoreContext(TenantId))
var entitiesQuery = ctx.MyEntity
.Include(i => i.EntityA)
.Include(i => i.GeneralType);
var myEntity = entitiesQuery.FirstOrDefault(e => e.Id == myGuid);
// check if myEntity.GeneralType is of the specialized type then query depending on the properties of this type
var specificEntity = myEntity.GeneralType as SpecificType;
if (specificEntity != null)
var myLocalization = ctx.Localizations.Where(l => l.Id == specificEntity.LocalizationId)
// Entity Framework is automatically setting myEntity.Localization to myLocalization
我不明白的是,Entity Framework 如何附加/设置内存对象的关系。请注意,内存中的对象不是代理 - 否则我会理解为什么会这样。
当我使用.AsNoTracking()
时,上述行为不起作用。
【问题讨论】:
我认为您误解了延迟加载的含义。禁用它意味着当您访问不在上下文中的导航属性时,EF 不会自动额外访问数据库(因为它没有被Include
急切加载,或通过查询显式获取)。但是如果该导航属性中的实体已经在上下文中(因为它之前已经被查询并附加到上下文中)你会看到它,因为 EF 知道实体之间的关系,并且导航属性只是一个参考到上下文中的实体。
关于代理,如果启用延迟加载,则必须启用它们,但是在某些情况下您启用代理并禁用延迟加载。代理与跟踪实体状态有关。 Here 你可以找到ProxyCreationEnabled
和LazyLoadingEnabled
组合值的解释。
也许您想发表您的评论作为答案,以便我将其标记为解决方案。真的帮助我解决了我的理解问题。
【参考方案1】:
我认为您误解了延迟加载的含义。禁用它意味着当您访问不在上下文中的导航属性时,EF 不会自动额外访问数据库(因为它没有被Include
急切加载,或通过查询显式获取)。但是如果该导航属性中的实体已经在上下文中(因为它之前已经被查询并附加到上下文中)你会看到它,因为 EF 知道实体之间的关系,并且导航属性只是一个参考到上下文中的实体。
关于代理,如果启用延迟加载,则必须启用它们,但在某些情况下您启用代理并禁用延迟加载。代理与跟踪实体状态有关。 Here你可以找到ProxyCreationEnabled
和LazyLoadingEnabled
组合值的解释
【讨论】:
另请注意,此“关系修复”是 EF 更改跟踪器的一项功能。如果您禁用查询的更改跟踪,它将禁用此行为。以上是关于尽管代理被禁用,实体框架会自动设置关系的主要内容,如果未能解决你的问题,请参考以下文章
我应该使用实体框架 4.1 和 MVC3 启用或禁用动态代理吗?