3

I´m using the example bellow, from http://ef.readthedocs.org/en/latest/getting-started/aspnet5.html, to test asp.net 5 and EF7:

using Microsoft.Data.Entity;
using System.Collections.Generic;

namespace EFGetStarted.AspNet5.Models
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Make Blog.Url required
            modelBuilder.Entity<Blog>()
                .Property(b => b.Url)
                .Required();
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}

But in my test, the

public List<Post> Posts { get; set; }

is always null. This look to be obvious because it is not instantiate.

What I have to do to get a behavior like

myBlog.Posts

and get all the posts from this blog ?

Beetlejuice
  • 4,292
  • 10
  • 58
  • 84
  • [MSDN: Entity Framework Loading Related Entities](https://msdn.microsoft.com/en-us/data/jj574232.aspx). – CodeCaster Sep 14 '15 at 13:45
  • 2
    The question linked as an answer is not relevant because this is about Entity Framework 7 and linked question is for a previous version. – user3285954 Nov 09 '15 at 21:54

1 Answers1

4

You should specify the virtual keyword for navigation properties. It's because EF creates proxy objects (i.e. inheritors of your classes) to implement lazy-loading. These inheritors can override your virtual properties only:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public virtual List<Post> Posts { get; set; }
}

Alternatively you can explicitly enumerate tables/classes to include to result set:

// This statement fills Posts property:
var blog = dbContext.Blogs.Include(x => x.Posts).FirstOrDefault(x => x.Id == id);
Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29
  • Great answer for explaining _why_ it works and not just saying "do this: ____". – Wiseguy Sep 14 '15 at 13:45
  • The name "Posts" follows any convention? What if I need to use other name (like OldPosts) ? – Beetlejuice Sep 14 '15 at 14:14
  • @paulo You can use any names you like. EF will generate id properties for you. These properties can have names like *OldPosts_Id* and so on. If you want to control these names you may specify them manually in classes like **Blog** or **Post**, and then you should modify your **OnModelCreating** method to configure mapped/navigation properties matching. – Mark Shevchenko Sep 14 '15 at 14:27
  • The real problem is that EF 7 does not support relations yet. – Beetlejuice Sep 29 '15 at 16:59
  • @BeetleJuice As I can see, the EF team has already done the feature, https://github.com/aspnet/EntityFramework/wiki/Roadmap: *Implemented... relationships between entities based on navigation and foreign key properties*. I'll can check it tomorrow. – Mark Shevchenko Sep 29 '15 at 18:49
  • @BeetleJuice. As I can see, you're completely right. It seems we have to wait until November 5 for RC1. – Mark Shevchenko Oct 02 '15 at 09:43