2

We are converting our project from ObjectContext to dbContext. Our current problem is with the difference in how eager loading is handled.

Example context

public class Person
{
    public virtual ICollection<Email> Emails { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}
public class Email
{
    public string Address{ get; set; }
}
public class Post
{
    public string Content{ get; set; }
}

we have many pieces of code throughout the enterprise that expect the emails to be loaded and therefore call person.Emails.First() without thinking about it. So we need to make sure that Emails are eagerly loaded.

Sometimes we can just us Include

However, when we use projections in our data layer we are running into problems. i.e.

return context.Persons.Select(p=> new Top5VM {
    Person = p,
    TopPosts = p.Posts.Take(5)
};

We have a lot of code that relies on Top5VM and expects Person.Emails to be loaded.

No mater what we've tried we can not figure out where to put the Include (or Load) function call where it will actually make a difference .

With the ObjectContext we would just have a dummy property on the Top5VM called Emails. Once that was loaded, the ObjectContext had references to all of those Entities an therefore never needed to go back to the server even when we accessed them through the person object. But that no longer works with the DbContext

2 Answers 2

1

Figured it out. I need to set context.Configuration.LazyLoadingEnabled = false; any time I want to use projection to accomplish eager loading. Unless of course I want to access the loaded entities directly from the projection.

Sign up to request clarification or add additional context in comments.

Comments

0

You can do this by always using your own DbContext in between:

public class MyDbContext : DbContext
{
    public MyDbContext() : base()
    {
        Configuration.LazyLoadingEnabled = false;
    }
}

Then use this everywhere instead of a DbContext.

Alternately, if you have control of all the POCOs, you could just remove the virtual keyword from the related collections ... the virtual keyword is the magic hookup Microsoft uses for lazy loading.

EDIT

I also tend to do this as an extension method:

static class DbContextExtensions
{
    public static DbContext AsEagerLoadingContext(this IDbContext context)
    {
        context.Configuration.LazyLoadingEnabled = false;
        //context.Configuration.AutoDetectChangesEnabled = false;

        return context;
    }
}

Used as so, allowing lazy loading to be used or not as needed:

using (var context = new DbContext().AsEagerLoadingContext())
    context.Stuff.Select(s => s.AllTheThings);

2 Comments

Thank you. Most of the time I do want Lazy Loading. But I would like the ability to Eager Load when necessary (only the properties that I need) . The projection allows for that as long as I temporarily turn off the LazyLoading.
Since answering, I got a chance to look at how I do it in code at work - that looks something like this (see edit).

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.