EF7 RC, navigation properties and lazy loading

Jumping into the brave new world of .NET as open source has been an experience, to say the least. The feedback loop is tight, things change quickly, and it's definitely a different world than the days of big bang releases. I think it's a great thing, but admittedly, it makes the early adoption thing a lot harder. Sometimes I find myself disappointed (as with the deferred release of SignalR 3, for example). Still, the scope of the frameworks and the number of people working on them is impressive, and I look forward to this new world.

Entity Framework 7 is a total do-over, and to that end, it is different in a great many ways. I wanted to write about navigation properties and the way they work now (as of RC1), because it's an important departure from previous versions. In short, the lazy loading does not happen for navigation properties. The current road map says it's a high priority feature, as the feedback around GitHub is pretty, uh, "vibrant." Still, I imagine that since they planned to be feature complete for the RC, I'm not going to hold my breath.

I don't think this is as big of a deal as people are making it out to be, as it just requires a slightly different approach. You have to think about what you want when you build the actual query. For example, say you have a table called Posts with a navigation property called User that maps to a Users table. All of the conventions still work... there are no annotations or special model builder options to configure. Your classes can look like this:

public class Post
{
   public int PostID {get;set;}
   public int UserID {get;set;}
   public virtual User {get;set;}
}

public class User
{
   public int UserID {get;set;}
   public virtual ICollection<Post> {get;set;}
}

Again, the dbcontext is conventional:

public class BlogContext : DbContext
{
   public DbSet<Post> Posts { get; set; }
   public DbSet<User> Users { get; set; }
}

The big change is in the query. If you get some posts and want those User properties hydrated, you need to specify that up front. Your query will look something like this:

var posts = _context.Posts.Include(x => x.User);

If you look at the underlying SQL that's generated, you'll see a join as expected.

It's a little different, but I don't think it's different bad. Diving in and just now using it, this threw me off for an hour. Hopefully it will prevent you from doing the same.

3 Comments

Add a Comment

As it will appear on the website

Not displayed

Your website