sorting Self-Referencing Relationship

人走茶凉 提交于 2019-12-08 03:09:58

问题


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


回答1:


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



回答2:


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.



来源:https://stackoverflow.com/questions/35814586/sorting-self-referencing-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!