Предположим, вы используете EF Core
и ваша модель выглядит следующим образом:
public class XModel {
public int Id {get;set;}
public string Name {get;set;}
public string Size {get;set;}
public string Type {get;set;}
public int? ParentId {get;set;}
public XModel Parent {get;set;}
public IList<XModel> Children {get;set;}
}
Поскольку вы ожидаете модель с полем data
& children
.Давайте создадим для них модели DTO:
public class Data {
public int Id {get;set;}
public string Name {get;set;}
public string Size {get;set;}
public string Type {get;set;}
[JsonIgnore]
public int? ParentId {get;set;}
}
public class Dto {
public Data Data {get;set;}
public IList<Dto> Children{get;set;}
}
Давайте создадим метод расширения, который создает дерево
public static class TreeLikeExtensions
{
public static IList<Dto> BuildTrees(this IQueryable<XModel> models)
{
var dtos = models.Select(m =>new Dto{
Data = new Data { Id = m.Id, Name = m.Name, Size =m.Size, Type = m.Type, ParentId = m.ParentId, },
Children = null,
}).ToList();
return BuildTrees(null, dtos);
}
// private helper function that builds tree recursively
private static IList<Dto> BuildTrees(int? pid, IList<Dto> candicates)
{
var children = candicates.Where(c => c.Data.ParentId == pid).ToList();
if (children==null || children.Count() == 0){
return null;
}
foreach (var i in children){
i.Children= BuildTrees(i.Data.Id, candicates);
}
return children;
}
}
Чтобы получить деревья, просто вызовите BuildTrees()
:
var result = _context.XModel.BuildTrees();
Чтобы игнорировать свойство null
children при сериализации, просто добавьте параметры, как показано ниже:
// var settings= new JsonSerializerSettings{
// NullValueHandling = NullValueHandling.Ignore,
// ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
// }
Или настройте MVC Serivces в Startup.cs
:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(o =>{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
o.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
Рабочая демоверсия
![enter image description here](https://i.stack.imgur.com/VYs10.png)