首页 > 解决方案 > 解决了-也许?如何使用相关 DTO 的嵌套列表返回 DTO 列表

问题描述

在不使用 Automapper 的情况下,我试图将 DTO 列表映射到 DTO 列表的每个元素中。特别是在这个例子中,我希望 API 返回一个父母列表,其中每个父母都包含它的孩子列表和宠物列表。

我有一个 EF Core 项目,其中包含以下模型(使用完全定义的关系)并且存在于更大的数据库中。

有一个 Parent 对象,它有许多 Pet 对象和许多 Child 对象,如下所示:

EF 核心模型

    public class Parent
    {
        public int ParentId { get; set; }
        public string Name { get; set; }

        public List<Child> Children { get; set; }
        public List<Pet> Pets { get; set; }
    }

    public class Child
    {
        public int ChildId { get; set; }
        public string Name { get; set; }

        public int ParentId { get; set; }
        public Parent Parent { get; set; }
    }

    public class Pet
    {
        public int PetId { get; set; }
        public string Name { get; set; }

        public int ParentId { get; set; }
        public Parent Parent { get; set; }
    }

在不使用 Automapper 的情况下,我试图在控制器中使用 DTO 来发送数据。

我已按如下方式设置 DTO:

DTO

    public class ParentDTO
    {
        public int ParentId { get; set; }
        public string Name { get; set; }

        //Should these be List<> or IEnumerable<>?
        public IEnumerable<ChildDTO> Children { get; set; }
        public IEnumerable<PetDTO> Pets { get; set; }
    }

    public class ChildDTO
    {
        public int ChildId { get; set; }
        public string Name { get; set; }
    }

    public class PetDTO
    {
        public int PetId { get; set; }
        public string Name { get; set; }
    }

目前我的控制器看起来像这样:

控制器尝试 1

        // GET: api/Parents/
        [HttpGet]
        public IEnumerable<ParentDTO> GetParents()
        {

            var parents = from pa in _context.Parents
                          select new ParentDTO()
                          {
                              Name = pa.Name
                          };

            return parents;
        }

        // GET: api/Parents/GetParentsWith
        [HttpGet("[action]")]
        public IEnumerable<ParentDTO> GetParentsWith()
        {

            var parents = from pa in _context.Parents
                          select new ParentDTO()
                          {
                              Name = pa.Name,
                              //Not sure how to correctly do this below...
                              Children = (from c in _context.Children.Where(c => c.ParentId == pa.ParentId)
                                          select new ChildDTO()
                                          {
                                              Name = c.Name
                                          }),
                              Pets = (from pe in _context.Pets.Where(pet => pet.ParentId == pa.ParentId)
                                      select new PetDTO()
                                      {
                                          Name = pe.Name
                                      })
                          };

            return parents;
        }

我的GET: api/Parents/作品很好(因为我没有尝试制作嵌套列表),但是我如何像我想要做的那样将相关的子项和宠物项添加到父母 DTO 中GET: api/Parents/GetParentsWith

尝试这样做会出现错误:

Microsoft.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
....
...

我也试过:

控制器尝试 2

        // GET: api/Parents/GetParentsWith
        [HttpGet("[action]")]
        public IEnumerable<ParentDTO> GetParentsWith()
        {

            var parents = from pa in _context.Parents
                          select new ParentDTO()
                          {
                              Name = pa.Name,
                              Children = (from c in pa.Children
                                          select new ChildDTO()
                                          {
                                              Name = c.Name
                                          }),
                              Pets = (from pe in pa.Pets
                                      select new PetDTO()
                                      {
                                          Name = pe.Name
                                      })
                          };

            return parents;
        }

这也给出了错误:

Microsoft.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
....
...

我也试过:

控制器尝试 3

        // GET: api/Parents/GetParentsWith
        [HttpGet("[action]")]
        public IEnumerable<ParentDTO> GetParentsWith()
        {

            var parents = from pa in _context.Parents
                          select new ParentDTO()
                          {
                              ParentId = pa.ParentId,
                              Name = pa.Name
                          };

            foreach (ParentDTO parent in parents)
            {
                var children = from child in _context.Children where child.ParentId == parent.ParentId
                               select new ChildDTO()
                               {
                                   ChildId = child.ChildId,
                                   Name = child.Name
                               };

                var pets = from pet in _context.Pets
                           where pet.ParentId == parent.ParentId
                           select new PetDTO()
                           {
                               PetId = pet.PetId,
                               Name = pet.Name
                           };

                parent.Children = children;
                parent.Pets = pets;

            return parents;
        }

这不会引发任何错误,所以也许我在这里的正确轨道上,不幸的是它只是返回 null 我期望一组孩子或宠物的地方:

[
    {
        "parentId": 1,
        "name": "Ronald",
        "children": null,
        "pets": null
    },
    {
        "parentId": 2,
        "name": "Benjamin",
        "children": null,
        "pets": null
    },
    {
        "parentId": 3,
        "name": "Sally",
        "children": null,
        "pets": null
    },
    {
        "parentId": 4,
        "name": "Foobar",
        "children": null,
        "pets": null
    }
]

解决了!但我做对了吗?

我注意到parents它是一个 IQueryable,因此 foreach 中的分配没有按我预期的那样工作......我想我需要了解一些关于 IQueryable、IEnumerable 等的知识。

        // GET: api/Parents/GetParentsWith
        [HttpGet("[action]")]
        public ask<ActionResult<IEnumerable<ParentDTO>>> GetParentsWith()
        {

            var parents = (from pa in _context.Parents
                          select new ParentDTO()
                          {
                              ParentId = pa.ParentId,
                              Name = pa.Name
                          }).ToListAsync();

            foreach (ParentDTO parent in await parents)
            {
                var children = from child in _context.Children where child.ParentId == parent.ParentId
                               select new ChildDTO()
                               {
                                   ChildId = child.ChildId,
                                   Name = child.Name
                               };

                var pets = from pet in _context.Pets
                           where pet.ParentId == parent.ParentId
                           select new PetDTO()
                           {
                               PetId = pet.PetId,
                               Name = pet.Name
                           };

                parent.Children = children;
                parent.Pets = pets;
            }

            return parents;
        }

标签: c#asp.net-corelinq-to-sqlentity-framework-coredto

解决方案


推荐阅读