7

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.

2 Answers 2

12

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 
Sign up to request clarification or add additional context in comments.

7 Comments

There is not a property named GrandChildren. Do you mean this code: Include(p => p.Children.Select(c => c.Children)) ?
@Javad_Amiry: Yes. Actually, what I wrote as GrandChildren can be any navigation property - collection or reference. The pattern Include(x => x.SomeCollection.Select(c => c.SomeNavigationProperty)) just causes an Include for the next level. You can repeat that ad infinitum: Select on collections, simple dotted paths on references.
OK, this works correctly :D thanks a lot. In continues I need to order children (and so grand children) when fetching them. I'll edit your answer and put my first code, and final code created by your guidance to explain my issue. Please help me to complete the solution. Special thanks to pay attention to question. Regards
@Javad_Amiry: Better make a new question about your sorting problem because 1) more people will see a new question than an edit in my answer, and 2) I'm offline now :)
@ChrisMoschini: No, it hasn't changed. The expression overload of Include is still there. Make sure that you have included using System.Data.Entity; in your source file.
|
0

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); 

9 Comments

What are u talking about? Plz read the Q again: How can I load the Parent (level 1) whit all associated children (level 2) and for each child, associated grandchild (level 3) if any? I know how to map entities, and know how to load them in 2-level relationship Parent-Child. But I can't load a 3-level association. Just this!
What do you mean by "load"? Do you mean select?
Load from database, fetch from db, select. Like this: entity.DynamicPages.Where(d => d.ParentId == null).Include(d => d.Children).ToList(); I know this, but I want to load d.Children.Children that I can't ):
Updated my answer. Hopefully this is what you were looking for.
Now that I see Slauma's answer, I get what you were looking for. And I also learned something, so no problem.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.