1

Assume the following model. Note the self-referencing relationship "parent".

 public class Category 
    {
        public virtual long Id { get; set; }
        public virtual string Name { get; set; }
        public virtual Category Parent { get; set; }
        public virtual long? ParentId { get; set; }
    }

My data are as follows:

id   |    name   |  parentId
1--------tag 1 ----- null
2--------tag 2 ----- 1
3--------tag 3 ----- 1
4--------tag 4 ----- 2
5--------tag 5 ----- null
6--------tag 6 ----- null

I want to write a query that data will be sorted as follows

tag 1
----->tag 2
----->----->tag 4
----->tag 3
tag 5
tag 6

This is my code

var categorys = __categories
                .AsNoTracking()
                .ToList();

I do not know how to sort them

testStack201541
  • 119
  • 1
  • 9
  • Search about [Tree Data Structure](http://stackoverflow.com/questions/9860207/build-a-simple-high-performance-tree-data-structure-in-c-sharp) – NoName Mar 05 '16 at 13:28

2 Answers2

1

Well I would describe that more as hierarchical organisation as opposed to sorting, but here is an example of how you can achieve it quite simply. Note, this is not very optimised as the search for each Parent Category requires potentially a full scan of the entire Category list, but it's a good starting point:

    using System;
    using System.Collections.Generic;
    using System.Linq;

    namespace SimpleTree
    {
        public class Program
        {
            private static void Main(string[] args)
            {
                var categories = new List<Category>()
                {
                    new Category {Id = 1, Name = "tag 1"},
                    new Category {Id = 2, Name = "tag 2", ParentId = 1},
                    new Category {Id = 3, Name = "tag 3", ParentId = 1},
                    new Category {Id = 4, Name = "tag 4", ParentId = 2},
                    new Category {Id = 5, Name = "tag 5"},
                    new Category {Id = 6, Name = "tag 6"},
                };

                foreach (var category in categories)
                {
                    category.Parent = FindParent(categories, category.ParentId);
                }

                //pretty printing with indentation is left as an exercise for you :)
                foreach (var category in categories)
                {
                    Console.WriteLine("ID:{0} Name:{1} ParentID:{2}", category.Id, category.Name, category.ParentId);
                }
                Console.ReadLine();
            }

            private static Category FindParent(IEnumerable<Category> categories, long? parentId)
            {
                if (parentId == null) return null;
                return categories.FirstOrDefault(c => c.Id == parentId);
            }
        }


        public class Category 
        {
            public virtual long Id { get; set; }
            public virtual string Name { get; set; }
            public virtual Category Parent { get; set; }
            public virtual long? ParentId { get; set; }
        }
    }

Output

ID:1 Name:tag 1 ParentID:
ID:2 Name:tag 2 ParentID:1
ID:3 Name:tag 3 ParentID:1
ID:4 Name:tag 4 ParentID:2
ID:5 Name:tag 5 ParentID:
ID:6 Name:tag 6 ParentID:

Note that depending on your use case, you might find it useful to include a ChildCategories collection on the Category object, and fill this as well, so that it's easy to walk the tree in either direction.

Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51
0

Try this recursive function

  class Program
{
    static void Main(string[] args)
    {
        using (var db = new aaContext2())
        {
            Temp temp = new Temp();

            var cc = db.Catagory.FirstOrDefault();
            IList<Category> parentList =new List <Category>();
            foreach (Category catagory in db.Catagory.Where(cat => cat.ParentId == null))
            {
                parentList.Add(temp.Recursive(catagory.Id, catagory.Name));
            }
        }
    }
}
public class Temp{
    public Category Recursive(long parentId, string name)
    {
        Category catagory = new Category();
        catagory.Id = parentId; catagory.Name = name;
        using (var db = new aaContext2())
        {
            //base condition
            if (db.Catagory.Where(catagory1 => catagory1.ParentId == parentId).Count() < 1)
            {
                return catagory;
            }
            else
            {
                IList<Category> newCatagoryList = new List<Category>();
                foreach (Category cat in db.Catagory.Where(cata => cata.ParentId == parentId))
                {
                    newCatagoryList.Add(Recursive(cat.Id, cat.Name));
                }
                catagory.CatagoryList = newCatagoryList;
                return catagory;
            }
        }
    }
}
public class aaContext2 : DbContext
{
    public DbSet<Category> Catagory { get; set; }
}
public class Category
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Category Parent { get; set; }

    public virtual ICollection<Category> CatagoryList { get; set; }
    public virtual long? ParentId { get; set; }
}