.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 对象中显示 currentOrganizationhierarchypasswordHash

这里有两种选择 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": []
      }
    ]
  }
]