我有一个带有自引用子属性的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);
我走错了路吗?可以用不同的方式解决问题吗?
答案 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更新到实体框架的最新版本。