在视图中显示自我引用模型的孩子

时间:2013-10-06 05:40:31

标签: asp.net-mvc-4 entity-framework-5 code-first entity-relationship self-reference

我正在这个应用程序中开发ASP.NET MVC 4的应用程序我有一个类别和产品表, 我有一个用于保存类别的自引用模型:

public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public int? ParentId { get; set; }
        public virtual Category Parent { get; set; }

        public virtual ICollection<Category> Children { get; set; }


        public virtual ICollection<Product> Products { get; set; }
        public byte[] RowVersion { set; get; }
    }

在我的服务层中我使用这种方式获取类别列表(GetAll方法):

public class CategoryService : ICategoryService
{
        private readonly IDbSet<Category> _category;
        private readonly IUnitOfWork _uow;

        public CategoryService(IUnitOfWork uow)
        {
            _uow = uow;
            _category=uow.Set<Category>();
        }

        public IList<Category> GetAll()
        {
            return _category.Include(x => x.Parent)
                .ToList();
        }
}
下面的

是我将模型传递给局部视图的动作方法:

public ActionResult Categories()
        {
            var query = _categoryService.GetAll();
            return PartialView("_Categories",query);
        }

PartialView:

@model IEnumerable<SarbarzDarb.Models.Entities.Category>
@foreach (var item in Model)
{
    if (item.Parent != null)
    {
    <li class="dropdown">
        @Html.ActionLink(item.Parent.Name, actionName:"Category", controllerName: "Product", routeValues: new {Id=item.Id, productName=item.Name.ToSeoUrl() }, htmlAttributes:null)


    </li>
}
}

一切都很好,上面的代码显示我存储在数据库中的父类别,我在类别表中的数据是这样的:

Id  Name        RowVersion  ParentId
--  ------      ----------  --------
1   Parent1     NULL        1
2   Parent2     NULL        2
3   Child1      NULL        NULL
4   child2      NULL        NULL
5   child3      NULL        NULL

现在我的问题是如何在局部视图中显示儿童对象。
我应该在类别表中使用另一列来指定父和子之间的关系吗?例如,在上表中,我如何找出child 2或child3的父级是什么,依此类推?或者哪个父母是child1的父母? 下面的代码是我的类别模型的配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Category>()
           .HasOptional(c => c.Parent)
           .WithMany(c => c.Children)
           .HasForeignKey(p => p.ParentId);
            base.OnModelCreating(modelBuilder);
        } 

我搜索了很多例如here,但我没有得到答案。

2 个答案:

答案 0 :(得分:1)

我的想法应该有点不同。 ParentID不应等于id。这没有道理。因此,如果孩子可能只有一个父母,那么您可以按如下方式更改您的表格:

Id  Name        RowVersion  ParentId
--  ------      ----------  --------
1   Parent1     NULL        NULL
2   Parent2     NULL        NULL
3   Child1      NULL        1
4   child2      NULL        1
5   child3      NULL        2

现在要获得Parent1的孩子,你只需要进行如下查询。但对于PartialView,您甚至不需要此查询。

var children = db.Categories.Where(g=>g.Id == 1);

然后您可以修改您的视图:

@foreach (var item in Model)
{

    <li class="dropdown">
        @Html.ActionLink(item.Name, "Category", "Product", new {Id=item.Id, productName=item.Name.ToSeoUrl() }, null)
        <ul>
       @foreach (var child in item.children)
        {
            <li class="dropdown">
        @Html.ActionLink(child.Name, "Category", "Product", new {Id=child.Id, productName=child.Name.ToSeoUrl() }, null)
           </li>
         }
        </ul>

    </li>
 }

如果您的子类别可能有更多,然后是一个父类,您可以创建如下的连接表:

ParentId  ChildID 
--        ------      
2          3
1          3
1          4
2          5
1          5

答案 1 :(得分:1)

我解决了我的问题,我应该以{{1​​}}方式更改GetAll方法中的代码:

CategoryService

然后在我的部分观点中:

public IList<Category> GetAll()
        {

            return _category.Where(category => category.ParentId == null)
                            .Include(category => category.Children).ToList();
        }