Reputation: 4722
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
Upvotes: 2
Views: 214
Reputation: 4722
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.
Upvotes: 1
Reputation: 1561
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);
Upvotes: 0