开发者

LINQ to SQL - Grouping categories by parentId

开发者 https://www.devze.com 2022-12-31 07:52 出处:网络
I am trying to construct a navigation menu using a Categories table from my db. I have a similar layout as below in Categories table.

I am trying to construct a navigation menu using a Categories table from my db.

I have a similar layout as below in Categories table.

public List<Category> CategoryData = new List(new Category[] {  
                                        new Category{ CategoryId = 1, Name = "Fruit", ParentCategoryId = null},
                                        new Category{ CategoryId = 2, Name = "Vegetables", ParentCategoryId = null},
                                        new Category{ CategoryId = 3, Name = "Apples", ParentCategoryId = 1},
       开发者_如何学运维                                 new Category{ CategoryId = 4, Name = "Bananas", ParentCategoryId = 1},
                                        new Category{ CategoryId = 5, Name = "Cucumber", ParentCategoryId = 2},
                                        new Category{ CategoryId = 6, Name = "Onions", ParentCategoryId = 2}
                                );  }

The above should return something like

Fruit (parent)

 "===Apples, Bananas (child)

Vegetables (parent)

"===Cucumber, Onions (child)

I need to be able to pass this as some kind of 'grouped' (grouped by parentid) collection to my View.

How to do this?


It would seem like this is a good example of when translating your model to a viewModel would come in handy. As you could create a collection of CategoryViewModel which have a Childrens property of CategoryViewModel using the same technique describe by @thomas.

public class CategoryViewModel
{
     public int CategoryId { set; get; }
     public string CategoryName { set; get; }
     public int? ParentCategoryId { set; get; }
     public IEnumerable<CategoryViewModel> Children { set; set; }
}

public static IEnumerable<CategoryViewModel> GetAllCategoryViewModel(IList<Category> categories) 
{
      var query = GetChildren(null, categories);
      return query.ToList();

}

public static IEnumerable<CategoryViewModel> GetChildren(int? parentId, IList<Category> categories)
{
     var children = from category in categories
                    where category.ParentCategoryId == parentId
                    select  
                     new CategoryViewModel
                     {
                       CategoryId = category.CategoryId,
                       CategoryName = category.CategoryName,
                       ParentCategoryId = category.ParentCategoryId,
                       Children = GetChildren(category.CategoryId, categories)
                     };

     return children;
}


How about something like:

private void Test()
{
    var categoryData = new List
                                      {
                                          new Category {CategoryId = 1, Name = "Fruit", ParentCategoryId = null},
                                          new Category {CategoryId = 2, Name = "Vegetables", ParentCategoryId = null},
                                          new Category {CategoryId = 3, Name = "Apples", ParentCategoryId = 1},
                                          new Category {CategoryId = 4, Name = "Bananas", ParentCategoryId = 1},
                                          new Category {CategoryId = 5, Name = "Cucumber", ParentCategoryId = 2},
                                          new Category {CategoryId = 6, Name = "Onions", ParentCategoryId = 2}
                                      };
    var query = from category in categoryData
                where category.ParentCategoryId == null
                select category;

    foreach ( var item in query )
    {
        Debug.WriteLine( string.Format( "{0} (parent)", item.Name ) );
        Debug.WriteLine( GetChildren(item.CategoryId, categoryData  ) );
    }

}
private static string GetChildren( int parentCategoryId, IEnumerable categoryData)
{
    var children = ( from category in categoryData
                     where category.ParentCategoryId == parentCategoryId
                     select category.Name ).ToArray();

    return string.Format( "==={0} (child)", string.Join( ", ", children ) );
}


var list = from a in CategoryData
        join b in CategoryData on a.ParentCategoryId equals b.CategoryId into c
        from d in c.DefaultIfEmpty()
        where d != null
        select new {
            a.CategoryId,
            a.Name,
            a.ParentCategoryId,
            ParentName = d.Name
        };

returns

CategoryId  Name      ParentCategoryId  ParentName
3             Apples      1                 Fruit
4             Bananas     1                 Fruit
5             Cucumber    2                 Vegetables
6             Onions      2                 Vegetables

You can then loop through it in your view and format accordingly.

0

精彩评论

暂无评论...
验证码 换一张
取 消