Pregunta

I'm developing an application on ASP.NET MVC 4 in this application I have a category and product tables, I've a self referencing model for holding categories :

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

in my service layer I'm using this way to get list of categories (GetAll method) :

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

below is my my action method for passing model to partial view :

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

everything is fine and with above code it shows me parent category that stored in database, my data in category table is like this :

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

now my question is that How can I show children objects in partial view too.
Should I use another column in my category table for specifying relation between parent and child? for example in above table how can I find out that what is parent for child 2 or child3 and so on? or which parent is parent of child1?
below code is configuration for my category model:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

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

I've searched a lot for example here but I didn't get my answer.

¿Fue útil?

Solución 2

I solved my problem, I should have changed code inside GetAll method in CategoryService this way :

public IList<Category> GetAll()
        {

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

Then In my partial view :

@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>

}

Otros consejos

It should be a little bit differ to my mind. ParentID shouldn't be equal to id. It makes no sense. So if child may have only one parent, then you may change your table as follows:

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

Now to get children of Parent1 you just need to make query like following. But for your PartialView you don't even need this query.

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

Then you may modify your View:

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

If your child categories may have more, then one parent, you may create join table like this:

ParentId  ChildID 
--        ------      
2          3
1          3
1          4
2          5
1          5
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top