问题
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