Search code examples
entity-frameworkasp.net-mvc-3treeviewhtml-helperentity-framework-ctp5

EF CTP5 self referencing model with query


I have a POCO Menu class with a self reference children property:

public class Menu
{
   public int MenuID { get; set; }
   public int? ParentID { get; set; }
   public string Title { get; set; }
   ...
   public virtual Menu Parent { get; set; }
   public virtual ICollection<Menu> Children { get; set; }
}

As I don't want to actual delete any menu items, I set these in the database as deleted.
In a linq query I have no problem exluding the menu items that is marked as deleted.

My problem is that the Children property includes the menu items marked as deleted, when I'm combinding it with the treeview helper from Matt Hidiger: http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx.

childrenProperty(root) returns the items that is marked as deleted:

private static void AppendChildren<T>(StringBuilder sb, T root, Func<T, IEnumerable<T>> childrenProperty, Func<T, string> itemContent)
{
    var children = childrenProperty(root);
    if (children.Equals(null) && !children.Any())
    {
        sb.AppendLine("</li>");
        return;
    }

    sb.AppendLine("\r\n<ul>");
    foreach (T item in children)
    {
        RenderLi(sb, item, liContent, itemContent);
        AppendChildren(sb, item, childrenProperty, liContent, itemContent);
    }

    sb.AppendLine("</ul></li>");
}

Is it posible to alter the mapping in OnModelCreating so it includes a query where I can exclude the deleted menu items?

My self referencing mapping:

modelBuilder.Entity<Menu>().HasMany(m => m.Children).WithOptional().HasForeignKey(m => m.ParentID);

Am I on a wrong track? Can the problem be solved in a different way?


Solution

  • I ended up rewriting my html helper, so i could filter out the items marked as deleted.

    Matt Hidiger's sampel:

    <%= Html.TreeView("locations", Model.Locations, l => l.ChildrenLocations, l => l.Name) %>
    

    My fix:

    <%= Html.TreeView("locations", Model.Locations, l => l.ChildrenLocations.Where(x => x.Deleted == false), l => l.Name) %>
    

    And of course i updated to latest version of the entity framework through nuget.