Entity Framework 尽管代理被禁用,但自动设置关系
Entity Framework automatically sets relationship although proxies are disabled
我在理解 Entity Framework 如何连接内存中实体的实体关系时遇到了一些麻烦。
要使用 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 append/set 内存对象的关系如何。请注意,内存中的对象不是代理 - 否则我会理解为什么它会起作用。
当我使用 .AsNoTracking()
时,上述行为不起作用。
我认为您误解了延迟加载的含义。禁用它意味着当您访问不在上下文中的导航 属性 时,EF 不会自动额外访问数据库(因为它没有用 Include
急切地加载,或者用 Include
显式获取一个问题)。但是,如果该导航 属性 中的实体已经在上下文中(因为它之前已被查询并附加到上下文中),您将看到它,因为 EF 知道实体之间的关系,并且导航 属性 只是对上下文中实体的引用。
关于代理,如果启用了延迟加载,则必须启用它们,但在某些情况下,您启用代理并禁用延迟加载。代理与实体状态的跟踪有关。 Here 你可以找到 ProxyCreationEnabled
和 LazyLoadingEnabled
组合值的解释
我在理解 Entity Framework 如何连接内存中实体的实体关系时遇到了一些麻烦。
要使用 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 append/set 内存对象的关系如何。请注意,内存中的对象不是代理 - 否则我会理解为什么它会起作用。
当我使用 .AsNoTracking()
时,上述行为不起作用。
我认为您误解了延迟加载的含义。禁用它意味着当您访问不在上下文中的导航 属性 时,EF 不会自动额外访问数据库(因为它没有用 Include
急切地加载,或者用 Include
显式获取一个问题)。但是,如果该导航 属性 中的实体已经在上下文中(因为它之前已被查询并附加到上下文中),您将看到它,因为 EF 知道实体之间的关系,并且导航 属性 只是对上下文中实体的引用。
关于代理,如果启用了延迟加载,则必须启用它们,但在某些情况下,您启用代理并禁用延迟加载。代理与实体状态的跟踪有关。 Here 你可以找到 ProxyCreationEnabled
和 LazyLoadingEnabled