gpt4 book ai didi

c# - 使用 AutoMapper 将嵌套元素映射到相关列表

转载 作者:太空宇宙 更新时间:2023-11-03 12:23:31 25 4
gpt4 key购买 nike

我有两组对象

我在 C# 客户端应用程序中使用的对象:

public class EmployeeClient
{
public int Id { get; set; }

public int DepartmentId { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public string MiddleName { get; set; }
}

public class DepartmentClient
{
public int Id { get; set; }

public string Name { get; set; }
}

public class OrganizationClient
{
public int Id { get; set; }

public string Name { get; set; }

public List<DepartmentClient> Departments { get; set; }

public List<EmployeeClient> Employees { get; set; }
}

和 DTO:

public class EmployeeDto
{
public int Id { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public string MiddleName { get; set; }
}

public class DepartmentDto
{
public int Id { get; set; }

public string Name { get; set; }

public List<EmployeeDto> Employees { get; set; }
}

public class OrganizationDto
{
public int Id { get; set; }

public string Name { get; set; }

public List<DepartmentDto> Departments { get; set; }
}

我使用 AutoMapper,我需要配置映射客户端 -> DTO 和 DTO -> 客户端。我像这样实现了映射 DTO-> 客户端:

public class DtoToClientMappingProfile: Profile
{
public DtoToClientMappingProfile()
{
CreateMap<EmployeeDto, EmployeeClient>();

CreateMap<DepartmentDto, DepartmentClient>();

CreateMap<OrganizationDto, OrganizationClient>()
.ForMember(dest => dest.Employees, opt => opt.ResolveUsing(src => src.Departments.SelectMany(d => d.Employees)))
.AfterMap(AfterMap);
}

private void AfterMap(OrganizationDto dto, OrganizationClient client)
{
foreach (var department in dto.Departments)
{
foreach (var employee in department.Employees)
{
var clientEmployee = client.Employees.First(e => e.Id == employee.Id);
clientEmployee.DepartmentId = department.Id;
}
}
}
}

这不是通用的解决方案,但对我有用。

我只找到了一个如何实现映射 Client->DTO 的选项:

public class ClientToDtosMappingProfile : Profile
{
public ClientToDtosMappingProfile()
{
CreateMap<EmployeeClient, EmployeeDto>();

CreateMap<DepartmentClient, DepartmentDto>();

CreateMap<OrganizationClient, OrganizationDto>()
.AfterMap(AfterMap);
}

private void AfterMap(OrganizationClient client, OrganizationDto dto)
{
foreach (var employee in client.Employees)
{
var departmentDto = dto.Departments.First(d => d.Id == employee.DepartmentId);
if (departmentDto.Employees == null)
{
departmentDto.Employees = new List<EmployeeDto>();
}

var configuration = (IConfigurationProvider)new MapperConfiguration(cfg =>
{
cfg.AddProfiles(typeof(ClientToDtosMappingProfile));
});

var mapper = (IMapper)new Mapper(configuration);

var employeeDto = mapper.Map<EmployeeDto>(employee);
departmentDto.Employees.Add(employeeDto);
}
}
}

它有效,但我不喜欢这个解决方案,因为我每次映射对象时都应该创建新的 Mapper 实例。在我的真实代码中,Employee 有很多嵌套元素,并且映射是在多个配置文件中配置的。

关于如何更好地实现它有什么想法吗?

最佳答案

我使用 ResolutionContext 改进了我的代码。它允许不在 AfterMap 函数中创建映射器。

DtoToClientMappingProfile:

public class DtoToClientMappingProfile: Profile
{
public DtoToClientMappingProfile()
{
CreateMap<EmployeeDto, EmployeeClient>();

CreateMap<DepartmentDto, DepartmentClient>();

CreateMap<OrganizationDto, OrganizationClient>()
.ForMember(dest => dest.Employees, opt => opt.Ignore())
.AfterMap(AfterMap);
}

private void AfterMap(OrganizationDto dto, OrganizationClient client, ResolutionContext resolutionContext)
{
if (dto.Departments == null)
{
return;
}

client.Departments = new List<DepartmentClient>();
foreach (var department in dto.Departments)
{
var departmentClient = resolutionContext.Mapper.Map<DepartmentClient>(department);
client.Departments.Add(departmentClient);
if (department.Employees == null)
{
continue;
}

if (client.Employees == null)
{
client.Employees = new List<EmployeeClient>();
}

foreach (var employee in department.Employees)
{
var employeeClient = resolutionContext.Mapper.Map<EmployeeClient>(employee);
employeeClient.DepartmentId = department.Id;
client.Employees.Add(employeeClient);
}
}
}

ClientToDtosMappingProfile:

public class ClientToDtosMappingProfile : Profile
{
public ClientToDtosMappingProfile()
{
CreateMap<EmployeeClient, EmployeeDto>();

CreateMap<DepartmentClient, DepartmentDto>();

CreateMap<OrganizationClient, OrganizationDto>()
.AfterMap(AfterMap);
}

private void AfterMap(OrganizationClient client, OrganizationDto dto, ResolutionContext resolutionContext)
{
if (client.Employees == null)
{
return;
}

foreach (var employee in client.Employees)
{
var departmentDto = dto.Departments.First(d => d.Id == employee.DepartmentId);
if (departmentDto.Employees == null)
{
departmentDto.Employees = new List<EmployeeDto>();
}

var employeeDto = resolutionContext.Mapper.Map<EmployeeDto>(employee);
departmentDto.Employees.Add(employeeDto);
}
}
}

关于c# - 使用 AutoMapper 将嵌套元素映射到相关列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46186129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com