排序自引用关系

时间:2016-03-05 13:12:35

标签: c# entity-framework sorting linq-to-entities self-referencing-table

假设以下型号。注意自引用关系" 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; }
    }

我的数据如下:

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

我想写一个数据将按如下方式排序的查询

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

这是我的代码

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

我不知道如何对它们进行排序

2 个答案:

答案 0 :(得分:1)

我会将其描述为分层组织而不是排序,但这里有一个如何简单地实现它的例子。请注意,这不是很优化,因为搜索每个父Category可能需要对整个Category列表进行全面扫描,但这是一个很好的起点:

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

输出

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:

请注意,根据您的使用情况,您可能会发现在ChildCategories对象上添加Category集合很有用,并填写此内容,以便轻松行走任意方向的树。

答案 1 :(得分:0)

试试这个递归函数

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