Automapper 通过分组将 table 映射到嵌套的 class
Automapper map a table to nested class with grouping
我有 2 个 table:Staff
& Address
。
关系是1对多(假设1个员工可以有多个地址)。
- 员工
员工编号 |员工姓名
++++++++++++++++++++++++++
1 |莎拉
2 |史蒂文
3 |大卫
- 地址
地址 ID |员工编号
|街道
+++++++++++++++++++++++++++++++++++++++++++++
1个
| 1个
| 292橡树大道
2个
| 1个
|松园巷 560 号
3个
| 2个
| 1195 兰德尔驱动器
4个
| 2个
|渡轮街 728 号
5个
| 2个
|埃德塞尔路 4043 号
6个
| 3个
|石南木大道 4038 号
为了获取员工信息及其地址,我在 Address
table (Dapper ORM) 上使用了 LEFT JOIN 查询。
然后我得到这样的数据,
地址 ID |员工编号
|员工姓名 |街道
++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++
1个
| 1个
|莎拉 | 292橡树大道
2个
| 1个
|莎拉 |松园巷 560 号
3个
| 2个
|史蒂文 | 1195 兰德尔驱动器
4个
| 2个
|
史蒂文 |渡轮街 728 号
5个
| 2个
|史蒂文 |埃德塞尔路 4043 号
6个
| 3个
|大卫 |石南木大道 4038 号\
如何使用 AutoMapper 通过 staffId 将此数据映射到下面的 DTO?
public class StaffDto
{
public long StaffId { get; set; }
public string StaffName { get; set; }
public List<Address> Address { get; set; }
}
public class Address
{
public long AddressId { get; set; }
public string Address{ get; set; }
}
示例数据应该是这样的:
{
"staffId": 1,
"staffName": "Sarah",
"address":
[
{
"addressId": 1,
"street": "292 Oak Drive"
},
{
"addressId": 2,
"street": "560 Pine Garden Lane"
}
]
}
查阅了很多方法和资料。由于使用automapper时会用到多次循环,所以用automapper是无法达到这个要求的。但是找到了另一种方法。下面是一个例子。
根据您提供的模型生成数据库。
以正常方式获得Staffs
和Addresses
。然后,循环处理值。
public IActionResult get()
{
var staff = context.Staffs.ToList();
var address = context.Addresses.ToList();
foreach(var staf in staff)
{
staf.address = address.Where(x => x.StaffId == staf.StaffId).Select(x=> {
x.staffDto = null;
return x;
}).ToList();
}
return Ok(staff);
}
它可以得到那个结果。
您从地址加入员工而不是其他方式有点令人困惑,因为您不需要地址列表,而是员工及其地址列表。您根本不需要 Automapper,Dapper 可以很好地为您做到这一点。这应该可以解决问题:
var sql = "SELECT StaffId, StaffName. AddressId, Street FROM Staff INNER JOIN Address ON Staff.StaffId = Address.StaffId";
var staffDictionary = new Dictionary<int, StaffDto>();
var result = connection.Query<StaffDto, Adress, StaffDto>(sql,
(s, a) => {
StaffDto staff;
if (!staffDictionary.TryGetValue(s.StaffId, out staff))
{
staff = s;
staffDictionary.Add(staff);
}
staff.Address.Add(a);
return staff;
}, splitOn: "AddressId");
// Here are your staff
return staffDictionary;
这个想法是,如果你遇到一个“新”员工,你就把它添加到字典中,否则你就用你已经拥有的那个。在所有情况下,Address 都会添加到工作人员中。
您也许可以通过您的 LEFT JOIN 以某种方式完成这项工作,但我不明白您为什么会这样做。
我有 2 个 table:Staff
& Address
。
关系是1对多(假设1个员工可以有多个地址)。
- 员工
员工编号 |员工姓名
++++++++++++++++++++++++++
1 |莎拉
2 |史蒂文
3 |大卫 - 地址
地址 ID |员工编号 |街道
+++++++++++++++++++++++++++++++++++++++++++++
1个 | 1个 | 292橡树大道
2个 | 1个 |松园巷 560 号
3个 | 2个 | 1195 兰德尔驱动器
4个 | 2个 |渡轮街 728 号
5个 | 2个 |埃德塞尔路 4043 号
6个 | 3个 |石南木大道 4038 号
为了获取员工信息及其地址,我在 Address
table (Dapper ORM) 上使用了 LEFT JOIN 查询。
然后我得到这样的数据,
地址 ID |员工编号
|员工姓名 |街道
++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++
1个
| 1个
|莎拉 | 292橡树大道
2个
| 1个
|莎拉 |松园巷 560 号
3个
| 2个
|史蒂文 | 1195 兰德尔驱动器
4个
| 2个
|
史蒂文 |渡轮街 728 号
5个
| 2个
|史蒂文 |埃德塞尔路 4043 号
6个
| 3个
|大卫 |石南木大道 4038 号\
如何使用 AutoMapper 通过 staffId 将此数据映射到下面的 DTO?
public class StaffDto
{
public long StaffId { get; set; }
public string StaffName { get; set; }
public List<Address> Address { get; set; }
}
public class Address
{
public long AddressId { get; set; }
public string Address{ get; set; }
}
示例数据应该是这样的:
{
"staffId": 1,
"staffName": "Sarah",
"address":
[
{
"addressId": 1,
"street": "292 Oak Drive"
},
{
"addressId": 2,
"street": "560 Pine Garden Lane"
}
]
}
查阅了很多方法和资料。由于使用automapper时会用到多次循环,所以用automapper是无法达到这个要求的。但是找到了另一种方法。下面是一个例子。
根据您提供的模型生成数据库。
以正常方式获得Staffs
和Addresses
。然后,循环处理值。
public IActionResult get()
{
var staff = context.Staffs.ToList();
var address = context.Addresses.ToList();
foreach(var staf in staff)
{
staf.address = address.Where(x => x.StaffId == staf.StaffId).Select(x=> {
x.staffDto = null;
return x;
}).ToList();
}
return Ok(staff);
}
它可以得到那个结果。
您从地址加入员工而不是其他方式有点令人困惑,因为您不需要地址列表,而是员工及其地址列表。您根本不需要 Automapper,Dapper 可以很好地为您做到这一点。这应该可以解决问题:
var sql = "SELECT StaffId, StaffName. AddressId, Street FROM Staff INNER JOIN Address ON Staff.StaffId = Address.StaffId";
var staffDictionary = new Dictionary<int, StaffDto>();
var result = connection.Query<StaffDto, Adress, StaffDto>(sql,
(s, a) => {
StaffDto staff;
if (!staffDictionary.TryGetValue(s.StaffId, out staff))
{
staff = s;
staffDictionary.Add(staff);
}
staff.Address.Add(a);
return staff;
}, splitOn: "AddressId");
// Here are your staff
return staffDictionary;
这个想法是,如果你遇到一个“新”员工,你就把它添加到字典中,否则你就用你已经拥有的那个。在所有情况下,Address 都会添加到工作人员中。 您也许可以通过您的 LEFT JOIN 以某种方式完成这项工作,但我不明白您为什么会这样做。