Search code examples
entity-frameworkentity-framework-4.1ef-code-firstentity-framework-ctp5

EntityFramework code first and circular one-to-many reference


please help me with the following problem. i have a class, like

public class TopicItem
{
    public TopicItem()
    {
        _children = new List<TopicItem>();
    }
    public int Id { get; set; }
    public string Title { get; set; }
    public int? ParentId { get; set; }
    public TopicItem Parent { get; set; }
    public List<TopicItem> Children { get; set; }
}

and fluent

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<TopicItem>().HasKey(t => t.Id);
    modelBuilder.Entity<TopicItem>().Property(t => t.Title).IsRequired();
    modelBuilder.Entity<TopicItem>().Property(t => t.Alias);
    modelBuilder.Entity<TopicItem>().HasOptional(t => t.Parent).WithMany(t => t.Children).HasForeignKey(t => t.ParentId);
    //modelBuilder.Entity<TopicItem>().HasMany(t => t.Children).WithOptional(t => t.Parent).HasForeignKey(t => t.ParentId);
    base.OnModelCreating(modelBuilder);
}

but it isn't working. I'm trying to use it as follows:

public void Recursion(List<TopicItem> items)
{
    if (items != null)
    {
        foreach (var item in items)
        {
            Process(item);
        }
        Recursion(item.Children);
    }
}

Recursion(MyContext.TopicItems.Where(t => t.Parent == null).ToList())

but the children property for each parent entity is null.

is it possible to do it?


Solution

  • You must either make both Parent and Children virtual to support lazy loading (it can trigger really lot of queries to database) or you must explicitly tell EF to load Children by using eager loading. The problem with eager loading is that it doesn't work recursively it will load only as many levels as you tell EF.

    EF and its query mechanism is not very suitable for recursive relations (tree structures).