尽管代理已禁用,但实体框架会自动设置关系

时间:2017-07-03 14:14:05

标签: c# entity-framework proxy entity-framework-5

我在理解Entity Framework如何加入内存实体的实体关系方面遇到了一些麻烦。

要使用实体框架进行查询,请禁用代理创建和延迟加载:

public static CoreContext GetReadCoreContext()
{
    var context = GetCoreContext();
    context.Configuration.ProxyCreationEnabled = false;
    context.Configuration.LazyLoadingEnabled = false;
    return context;
}

由于我在ER模型中有一些继承的类型,并且我想仅在继承的类型是特定的类型时包含一些实体,我需要做两个单独的查询。只有特定类型包含与本地化的关系。请注意,这只是为了说明为什么我必须做两个单独的查询,并不一定与我理解实体框架的机制有关。

首先,我查询一般部分,它不依赖于特定类型:

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()时,上述行为无效。

1 个答案:

答案 0 :(得分:2)

我认为你误解了Lazy Loading的含义。禁用它意味着当您访问不在上下文中的导航属性时,EF不会自动额外访问数据库(因为它没有急切地加载Include,或者通过查询显式获得)。但是如果该导航属性中的实体已经在上下文中(因为它之前已被查询并附加到上下文中),您将看到它,因为EF知道实体之间的关系,导航属性只是一个参考到上下文中的实体。

关于Proxies,如果启用了延迟加载,则必须启用它们,但在某些情况下您可以启用代理并禁用延迟加载。代理与实体状态的跟踪有关。 Here您可以找到合并ProxyCreationEnabledLazyLoadingEnabled

值的说明