1

So LazyLoadingEnabled = false apparently doesn't do what I thought it did. And has next to no documentation.

I design my entity trees very carefully. I think hard about every relationship. When I load up an entity that is an Aggregate Root, I want everything that is navigable to from there to load. That's how the Aggregate root concept works after all, if I want something to be weekly related I'd stick an id on the entity and manage the relationship myself.

Is there a way to do this with Entity Framework?

2 Answers 2

2

You can try obtaining all NavigationProperties of the element type (in IQueryable). By accessing to the MetadataWorkspace of ObjectContext you can get those properties of a specific type and Include all easily.

Note that I suppose you're using EF5 or later version, whereas DbContext is used. We access to ObjectContext via the interface IObjectContextAdapter. Here is the code:

public static IQueryable<T> LoadAllRelatedObjects<T>(this IQueryable<T> source, DbContext context) {
        //obtain the EntityType corresponding to the ElementType first
        //then we can get all NavigationProperties of the ElementType
        var items = (ObjectItemCollection) ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace);            
        var entityType = items.OfType<EntityType>().Single(e => items.GetClrType(e) == source.ElementType);
        return entityType.NavigationProperties
                         .Aggregate(source, (c, e) => c.Include(e.Name));
}

Note in new version (since EF5), the namespace of ObjectItemCollection (and other metadata items) is System.Data.Entity.Core.Metadata.Edm, while in the old version (before EF5), it's System.Data.Metadata.Emd.

Usage:

yourModel.YourEntities.LoadAllRelatedObjects(yourModel)
         //. more query here ...
         ;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I'll probably write somethingw ith reflection...I really can't believe this isn't built in.
1

I don't think there's a way to have all of the navigation properties auto-eager load. How about making an extension method instead?

public static IQueryable<Company> LoadCompany(this IQueryable<Company> query) {
     return query.Include(x => x.Divisions)
                 .Include(x => x.Departments)
                 .Include(x => x.Employees);
}

Example:

var query = from company in db.Companies.LoadCompany()
            where company.Name == "Microsoft"
            select company;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.