c# - 解决了-也许?如何使用相关 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;
}
解决方案
推荐阅读
- unity3d - 为什么从assetBundle添加MeshCollider时网格被标记为不可访问以及如何解决?
- html - 绝对 DIV 占用所有剩余高度
- mediawiki - mediawiki 嵌套多个函数(下划线)
- excel - 日期的宏检查 => 如果真正将行复制到第二张纸
- python - 熊猫数据框获取每组的第一行并复制到其他行
- html - 如何在 Thymeleaf 页面中显示 Angular 组件?
- angular - 如何在 Angular 中设置动态 HTML 数据?
- html - css 中的悬停样式不适用于我的按钮
- nativescript - 如何在 nativescript 中控制台表单数据
- java - 从 excel 读取数据单元格值