具有查询功能的EF CTP5自引用模型

时间:2011-03-10 21:22:53

标签: entity-framework asp.net-mvc-3 treeview html-helper entity-framework-ctp5

我有一个带有自引用子属性的POCO Menu类:

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

由于我不想实际删除任何菜单项,我在数据库中将它们设置为已删除 在linq查询中,我没有问题排除标记为已删除的菜单项。

我的问题是,当我将其与Matt Hidiger的树视图帮助器合并时,Children属性包括标记为已删除的菜单项:http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx

childrenProperty(root)返回标记为已删除的项目:

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

是否可以在OnModelCreating中更改映射,因此它包含一个查询,我可以在其中排除已删除的菜单项?

我的自我引用映射:

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

我走错了路吗?可以用不同的方式解决问题吗?

2 个答案:

答案 0 :(得分:0)

你难道不能在枚举它之前过滤列表吗?

foreach (T item in children.Where(x => x.IsDeleted == false)
{
    RenderLi(sb, item, liContent, itemContent);
    AppendChildren(sb, item, childrenProperty, liContent, itemContent);
}

答案 1 :(得分:0)

我最终重写了我的html助手,因此我可以过滤掉标记为已删除的项目。

Matt Hidiger的样本:

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

我的修复:

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

当然,我通过nuget更新到实体框架的最新版本。