【问题标题】:Showing child in self referencing model in view在视图中显示自引用模型中的子项
【发布时间】:2013-10-06 05:40:31
【问题描述】:

我正在这个应用程序中开发一个基于 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);
        }

部分视图:

@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

现在我的问题是如何在局部视图中显示子对象。
我应该在类别表中使用另一列来指定父子之间的关系吗?例如在上表中,我如何找出孩子 2 或孩子 3 的父母等等?或者哪个父母是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,但我没有得到答案。

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 谢谢,我的类别课程呢?可以吗?我的意思是它的设计和模型创建时的配置。
    • @SirwanAfifi 在我看来这绝对是正常的。对我来说应该可以。
    【解决方案2】:

    我解决了我的问题,我应该在CategoryService 中更改GetAll 方法内的代码:

    public IList<Category> GetAll()
            {
    
                return _category.Where(category => category.ParentId == null)
                                .Include(category => category.Children).ToList();
            }
    

    那么在我的部分观点中:

    @model IEnumerable<SarbarzDarb.Models.Entities.Category>
    @foreach (var item in Model)
    {
    
        <li class="dropdown">
            @Html.ActionLink(item.Name, actionName: "Category", controllerName: "Product", routeValues: new { Id = item.Id, productName = item.Name.ToSeoUrl() }, htmlAttributes: null)
    
            <ul class="dropdown-menu">
                @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>
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 2015-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      相关资源
      最近更新 更多