1

I have some troubles with understanding how Entity Framework is joining entity relations for in-memory entities.

To query with the Entity Framework I disable proxy creation and lazy loading:

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

Since I have some inherited types in the ER model and I want to include some entities only when the inherited type is a specific one, I need to do two separate queries. Only a specific type contains a relationship to Localization. Please not that this is only to illustrate why I have to do two separate queries and is not necessarily related to my struggles to understand Entity Framework's mechanism.

Firstly I query the general part, which is not dependent on the specific type:

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
    }
}

What I don't understand is, how does Entity Framework append/set the relation for the in-memory object. Note that the in-memory object is no proxy - otherwise I'd understand why that is working.

When I use .AsNoTracking() the above described behavior is not working.

officer
  • 2,080
  • 1
  • 20
  • 29
  • 1
    I think you are misinterpreting the meaning of Lazy Loading. Disabling it means that EF will not do automatic extra trips to the database when you access a navigation property which is not in the context (because it has not been eagerly loaded with an `Include`, or explicitly obtained with a query). But if the entity in that navigation property is already in the context (because it has been queried and attached to the context before) you will see it, as EF is aware of the relationships between the entities, and a navigation property is just a reference to an entity in the context. – Diana Jul 03 '17 at 20:30
  • And about Proxies, they have to be enabled if Lazy Loading is enabled, but there are some scenarios where you enable Proxies and disable Lazy Loading. Proxies are related to tracking of entities states. [Here](https://stackoverflow.com/questions/25720006/ef-6-1-difference-between-proxycreationenabled-and-lazyloadingenabled) you can find an explanation of combining values of `ProxyCreationEnabled` and `LazyLoadingEnabled`. – Diana Jul 03 '17 at 20:52
  • Maybe you want to post your comment as an answer so I can mark it as the solution. Really helped me with my problem in understanding. – officer Oct 13 '17 at 07:42

1 Answers1

2

I think you are misinterpreting the meaning of Lazy Loading. Disabling it means that EF will not do automatic extra trips to the database when you access a navigation property which is not in the context (because it has not been eagerly loaded with an Include, or explicitly obtained with a query). But if the entity in that navigation property is already in the context (because it has been queried and attached to the context before) you will see it, as EF is aware of the relationships between the entities, and a navigation property is just a reference to an entity in the context.

And about Proxies, they have to be enabled if Lazy Loading is enabled, but there are some scenarios where you enable Proxies and disable Lazy Loading. Proxies are related to tracking of entities states. Here you can find an explanation of combining values of ProxyCreationEnabled and LazyLoadingEnabled

Diana
  • 2,186
  • 1
  • 20
  • 31