EF code-first: How to load related data (parent-child-grandchild)?


Question

I have this entity:

public class DynamicPage {

    public int PageId { get; set; }

    public int Order { get; set; }

    public string MenuText { get; set; }

    public string MenuHover { get; set; }

    public int? ParentId { get; set; }

    public virtual DynamicPage Parent { get; set; }

    public virtual ICollection<DynamicPage> Children { get; set; }
}

This entity may have 3 level: Parent -> Child -> Grandchild. How can I load the Parent (level 1) whit all associated children (level 2) and for each child, associated grandchild (level 3) if any? Thanks to help.

Accepted Answer

EF 4.1 feature and syntax:

var entity = context.Parents
    .Include(p => p.Children.Select(c => c.GrandChildren))
    .FirstOrDefault(p => p.Id == 1); // or whatever condition

Popular Answer

If you want to make life easy on yourself, follow the EF Code First conventions of naming your table IDs simply Id (or, alternatively, name of table + Id, e.g., DyanmicPageId).

This should leave you with something like this:

public class DynamicPage
{
    public int Id { get; set; }
    public int Order { get; set; }
    public string MenuText { get; set; }
    public string MenuHover { get; set; }
    public int? ParentId { get; set; }

    public virtual DynamicPage Parent { get; set; }
    public virtual ICollection<DynamicPage> Children { get; set; }
}

Then you need to set up the relationship between parents and children explicitly in an OnModelCreating method in your DbContext class.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<DynamicPage>()
        .HasMany(page => page.Children)
        .WithRequired(child => child.Parent)
        .HasForeignKey(child => child.ParentId);
}

You can then select children or grandchildren as needed:

var parent = dbContext.DynamicPages.Where(page => page.ParentId == null);
var children = parent.Children;
var grandchildren = parent.SelectMany(page => page.Children);
var allRelatedPages = parent.Union(children).Union(grandchildren);




Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why