Loading multiple navigation properties on one context call

c# entity-framework-core


I'm writing a C# application that utilizes EF Core to generate all my relationships to my db. I'm currently trying to load some relationships only when I need them (which in this case is when I'm trying to delete records).

I'm trying to use Context.Entry in order to load the relationships required only when I need them, see below:

await Context.Entry(entity).Collection(e => e.DBTable1).LoadAsync();
await Context.Entry(entity).Collection(e => e.DBTable2).LoadAsync();

What I'm curious about is if you can combine multiple relationships into a single load statement, something like below:

await Context.Entry(entity).Collection(e => e.DBTable1 && e => e.DBTable2).LoadAsync();

I know I can use .Include/.ThenInclude to build the relationships before i execute the EF query, however, my workflow requires that the relationships be loaded after the query has been executed.

9/21/2018 7:31:47 PM

Accepted Answer

Tracked entities in EF should have their nav properties/collections populated when the requisite data is loaded. Try projecting the desired properties/collections into an anonymous type and verifying the expected properties are populated in your original entity object:

await dbContext.Set<TEntity>()
    .Where( e => e.Id == entity.Id )
    .Select( e => new
        DoesntMatter01 = e.DBTable1,
        DoesntMatter02 = e.DBTable2,
    } )

Note you don't actually care about the result as long as the query is enumerated. In this case we're using SingleOrDefault but it's possible to load these properties for all tracked entities of a given type in the same manner if we select the IDs of a collection of entities then use ids.Contains( e.Id ) in the where predicate and then enumerating via a call to ToArray or similar method that will return all results.

Run that and verify the collection properties are now populated as expected.

Edit: since I felt so motivated:

public Task LoadEntityCollections( DbContext dbContext, IEnumerable<EntityType> entities )
        .Where( e => entities.Select( ei => ei.Id ).Contains( e.Id ) )
        .Select( e => new
            // assign from properties you want loaded
        } )
9/21/2018 7:49:25 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow