.net core 3.0实体无限循环
.net core 3.0 entity infinite loop
我在获取数据时遇到了 .net 核心实体的一些问题。
这是我的控制器代码
_context.Hierarchies
.Include(i => i.Children)
.AsEnumerable()
.Where(x => x.Parent == null)
.ToList();
这是我的模特Class
public class Hierarchy
{
public Hierarchy()
{
CreatedDate = DateTime.UtcNow;
Children = new List<Hierarchy>();
}
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public List<Task> Tasks{ get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
这是我的数据库上下文模型构建器
modelBuilder.Entity<Hierarchy>(hierarchy => {
hierarchy.HasMany(c => c.Children)
.WithOne(c => c.Parent)
.HasForeignKey(c => c.ParentId);
});
当调用我的 api 结果是
[
{
"id": 16,
"name": "category1",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null,
"currentOrganization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": [
{
"id": 17,
"name": "category2",
"description": null,
"createdDate": "2020-04-08T02:09:46.1474742Z",
"tasks": [],
"parentId": 16,
"children": []
}
]
}
},
"createdDate": "2020-04-08T02:09:34.54658",
"organization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": [
{
"id": 17,
"name": "category2",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null
},
"createdDate": "2020-04-08T02:09:46.1474742Z",
"tasks": [],
"parentId": 16,
"children": []
}
]
},
"tasks": null,
"parent": null,
"parentId": null,
"children": [
{
"id": 17,
"name": "category2",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null,
"currentOrganization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": []
}
},
"createdDate": "2020-04-08T02:09:46.1474742Z",
"organization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": []
},
"tasks": [],
"parentId": 16,
"children": []
}
]
}
]
其创建方式 -> 当前组织 -> 层次结构
我不需要 currentOrganization 和 hierarchy
createdBy 对象也有用户 passwordHash
如何自定义我的 return 值;
这应该取决于您序列化模型的方式。但一般来说,创建一个仅返回相关数据的 DTO 在大多数情况下可能是最佳选择。在您的情况下,DTO 只能包含 IserId 而不是 User 对象。此外,如果您坚持要返回数据库实体,则可以在返回之前设置对象值 'null' 或在从数据库中获取实体时不设置 'including' 不相关的对象。 .
i dont need currentOrganization and hierarchy also createdBy object has user passwordHash
您似乎不想在 createdBy
对象中显示 currentOrganization
、hierarchy
和 passwordHash
。
这里有两种选择 return 值的方法:
1.Use JsonIgnore 属性:
public class Hierarchy
{
public Hierarchy()
{
CreatedDate = DateTime.UtcNow;
Children = new List<Hierarchy>();
}
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
public class User
{
public int Id { get; set; }
public string Email { get; set; }
//more properties...
[Newtonsoft.Json.JsonIgnore]
public string PasswordHash { get; set; }
[Newtonsoft.Json.JsonIgnore]
public Organization CurrentOrganization { get; set; }
}
public class Organization
{
public int Id { get; set; }
public string Name { get; set; }
//more properties...
public List<Hierarchy> Hierarchies { get; set; }
}
控制器:
var d = _context.Hierarchies
.Include(i=>i.Organization)
.Include(i => i.Children)
.Include(i => i.CreatedBy)
.Where(x => x.Parent == null)
.AsEnumerable()
.ToList();
Startup.cs:
services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
2.Create 新视图模型:
视图模型:
public class HierarchyViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public UserViewModel CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
public class UserViewModel
{
public int Id { get; set; }
public string Email { get; set; }
}
控制器:
var d = _context.Hierarchies
.Include(i=>i.Organization)
.Include(i => i.Children)
.Include(i => i.CreatedBy)
.Where(x => x.Parent == null)
.Select(x => new HierarchyViewModel()
{
Id = x.Id,
CreatedDate = x.CreatedDate,
Description = x.Description,
Name = x.Name,
Parent = x.Parent,
Children = x.Children,
CreatedBy = new UserViewModel()
{
Id = x.CreatedBy.Id,
Email = x.CreatedBy.Email
},
ParentId = x.ParentId,
Organization = x.Organization
}).ToList();
结果:
[
{
"id": 9,
"name": "bbb",
"description": "abb",
"createdBy": {
"id": 3,
"email": "email2"
},
"createdDate": "2019-08-07T00:00:00",
"organization": {
"id": 1,
"name": "org1",
"hierarchies": [
{
"id": 8,
"name": "asd",
"description": "sda",
"createdBy": null,
"createdDate": "2019-08-06T00:00:00",
"parent": null,
"parentId": 9,
"children": []
}
]
},
"parent": null,
"parentId": null,
"children": [
{
"id": 8,
"name": "aaa",
"description": "aaa",
"createdBy": null,
"createdDate": "2019-08-06T00:00:00",
"organization": {
"id": 1,
"name": "org1",
"hierarchies": []
},
"parent": null,
"parentId": 9,
"children": []
}
]
}
]
我在获取数据时遇到了 .net 核心实体的一些问题。
这是我的控制器代码
_context.Hierarchies
.Include(i => i.Children)
.AsEnumerable()
.Where(x => x.Parent == null)
.ToList();
这是我的模特Class
public class Hierarchy
{
public Hierarchy()
{
CreatedDate = DateTime.UtcNow;
Children = new List<Hierarchy>();
}
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public List<Task> Tasks{ get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
这是我的数据库上下文模型构建器
modelBuilder.Entity<Hierarchy>(hierarchy => {
hierarchy.HasMany(c => c.Children)
.WithOne(c => c.Parent)
.HasForeignKey(c => c.ParentId);
});
当调用我的 api 结果是
[
{
"id": 16,
"name": "category1",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null,
"currentOrganization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": [
{
"id": 17,
"name": "category2",
"description": null,
"createdDate": "2020-04-08T02:09:46.1474742Z",
"tasks": [],
"parentId": 16,
"children": []
}
]
}
},
"createdDate": "2020-04-08T02:09:34.54658",
"organization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": [
{
"id": 17,
"name": "category2",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null
},
"createdDate": "2020-04-08T02:09:46.1474742Z",
"tasks": [],
"parentId": 16,
"children": []
}
]
},
"tasks": null,
"parent": null,
"parentId": null,
"children": [
{
"id": 17,
"name": "category2",
"description": null,
"createdBy": {
"id": 2,
"email": "test@test.com",
"passwordHash": "IR4uM8YiGpzevGjNYQHfFgFBkHqTqGy3rgCsA8d9LNZAmTItvy2l3MXSnPcXQD7QldV3X5GA/CKSF4mPCFkAYg==",
"passwordSalt": "XWzpfAf8IA7wpgY+gtVHiGPxTX4avvn38VY7MFspMhAfPUwL1a9ctuSQcEPlRJKqfK/3yZRtPWUlMQV7XH0JHRd4bKFvH/NKpSr4v46vOlgdQWAZDH1dklmqPtCmYK/Rq8SC/qcKfrmQLbJewBJ7B1Fse33ohAXp29+0K1c4YsE=",
"name": null,
"avatar": null,
"address": null,
"aboutMe": null,
"company": null,
"job": null,
"city": null,
"country": null,
"birthday": "0001-01-01T00:00:00",
"createdDate": "2020-04-08T02:38:40.288739",
"userOrganizations": null,
"ownerTasks": null,
"assignedTasks": null,
"assigneeTasks": null,
"currentOrganization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": []
}
},
"createdDate": "2020-04-08T02:09:46.1474742Z",
"organization": {
"id": 2,
"name": "Default",
"description": "",
"createdDate": "2020-04-07T23:38:40.459297",
"userOrganizations": [],
"hierarchies": []
},
"tasks": [],
"parentId": 16,
"children": []
}
]
}
]
其创建方式 -> 当前组织 -> 层次结构
我不需要 currentOrganization 和 hierarchy createdBy 对象也有用户 passwordHash
如何自定义我的 return 值;
这应该取决于您序列化模型的方式。但一般来说,创建一个仅返回相关数据的 DTO 在大多数情况下可能是最佳选择。在您的情况下,DTO 只能包含 IserId 而不是 User 对象。此外,如果您坚持要返回数据库实体,则可以在返回之前设置对象值 'null' 或在从数据库中获取实体时不设置 'including' 不相关的对象。 .
i dont need currentOrganization and hierarchy also createdBy object has user passwordHash
您似乎不想在 createdBy
对象中显示 currentOrganization
、hierarchy
和 passwordHash
。
这里有两种选择 return 值的方法:
1.Use JsonIgnore 属性:
public class Hierarchy
{
public Hierarchy()
{
CreatedDate = DateTime.UtcNow;
Children = new List<Hierarchy>();
}
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
public class User
{
public int Id { get; set; }
public string Email { get; set; }
//more properties...
[Newtonsoft.Json.JsonIgnore]
public string PasswordHash { get; set; }
[Newtonsoft.Json.JsonIgnore]
public Organization CurrentOrganization { get; set; }
}
public class Organization
{
public int Id { get; set; }
public string Name { get; set; }
//more properties...
public List<Hierarchy> Hierarchies { get; set; }
}
控制器:
var d = _context.Hierarchies
.Include(i=>i.Organization)
.Include(i => i.Children)
.Include(i => i.CreatedBy)
.Where(x => x.Parent == null)
.AsEnumerable()
.ToList();
Startup.cs:
services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
2.Create 新视图模型:
视图模型:
public class HierarchyViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public UserViewModel CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public Organization Organization { get; set; }
public Hierarchy Parent { get; set; }
public long? ParentId { get; set; }
public List<Hierarchy> Children { get; set; }
}
public class UserViewModel
{
public int Id { get; set; }
public string Email { get; set; }
}
控制器:
var d = _context.Hierarchies
.Include(i=>i.Organization)
.Include(i => i.Children)
.Include(i => i.CreatedBy)
.Where(x => x.Parent == null)
.Select(x => new HierarchyViewModel()
{
Id = x.Id,
CreatedDate = x.CreatedDate,
Description = x.Description,
Name = x.Name,
Parent = x.Parent,
Children = x.Children,
CreatedBy = new UserViewModel()
{
Id = x.CreatedBy.Id,
Email = x.CreatedBy.Email
},
ParentId = x.ParentId,
Organization = x.Organization
}).ToList();
结果:
[
{
"id": 9,
"name": "bbb",
"description": "abb",
"createdBy": {
"id": 3,
"email": "email2"
},
"createdDate": "2019-08-07T00:00:00",
"organization": {
"id": 1,
"name": "org1",
"hierarchies": [
{
"id": 8,
"name": "asd",
"description": "sda",
"createdBy": null,
"createdDate": "2019-08-06T00:00:00",
"parent": null,
"parentId": 9,
"children": []
}
]
},
"parent": null,
"parentId": null,
"children": [
{
"id": 8,
"name": "aaa",
"description": "aaa",
"createdBy": null,
"createdDate": "2019-08-06T00:00:00",
"organization": {
"id": 1,
"name": "org1",
"hierarchies": []
},
"parent": null,
"parentId": 9,
"children": []
}
]
}
]