英文:
Using AutoMapper for classes with constructors and nested lists
问题
I have translated the code-related content as requested:
我有两个实体:User 和 UserQuota。 "User" 包含一个配额列表。
我需要将这些类映射到DTO对象:UserWebDtoWithQuotas 和 UserQuotaWebDto,其中 UserWebDtoWithQuotas 还包含一个 UserQuotaWebDto 列表。
在我的项目中,我倾向于在定义类时使用严格构造函数,因此我的DTO看起来像这样:
public record UserWebDtoWithQuotas
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuotaWebDto> Quotas { get; private init; }
public UserWebDtoWithQuotas(Guid userId, string username, List<UserQuotaWebDto> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
我尝试了只定义两个映射规则,像这样:
CreateMap<User, UserWebDtoWithQuotas>();
CreateMap<UserQuota, UserQuotaWebDto>();
但是这会引发错误 "Type 'Application.Operations.Users.DTOs.UserWebDtoWithQuotas' 没有默认构造函数 (参数 'type')"。
我尝试在映射配置文件中使用 ".constructUsing",当它只有一行代码时,它可以工作:
CreateMap<User, UserWebDtoWithQuotas>()
.ConvertUsing(user => new UserWebDtoWithQuotas(user.Id, user.Username, new List<UserQuotaWebDto>()));
但是当我尝试实际映射嵌套列表时,像这样:
CreateMap<User, UserWebDtoWithQuotas>()
.ConstructUsing((user, context) =>
{
var quotas = context.Mapper.Map<List<UserQuotaWebDto>>(user.Quotas);
return new UserWebDtoWithQuotas(user.Id, user.Username, quotas);
});
它再次引发相同的 "没有默认构造函数" 错误。
我做错了什么?是否有可能创建复杂的自定义对象构造规则?
Please note that I've provided a translation of the code-related content only, as requested. If you have any further questions or need assistance with the code, please feel free to ask.
英文:
I have two entities: User, and UserQuota. "User" contains a list of quotas.
I need to map from these classes to DTO objects: UserWebDtoWithQuotas and UserQuotaWebDto, where UserWebDtoWithQuotas would also contain a list of UserQuotaWebDto's.
I tend to use strict constructors when defining classes in my project, so my DTOs look something like this:
public record UserWebDtoWithQuotas
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuotaWebDto> Quotas { get; private init; }
public UserWebDtoWithQuotas(Guid userId, string username, List<UserQuotaWebDto> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
I tried just defining two mapping rules, like this:
CreateMap<User, UserWebDtoWithQuotas>();
CreateMap<UserQuota, UserQuotaWebDto>();
But this throws an error "Type 'Application.Operations.Users.DTOs.UserWebDtoWithQuotas' does not have a default constructor (Parameter 'type')".
I tried to use ".constructUsing" in the mapper profile, and it works when it's just one line of code:
CreateMap<User, UserWebDtoWithQuotas>()
.ConvertUsing(user => new UserWebDtoWithQuotas(user.Id, user.Username, new List<UserQuotaWebDto>()));
But then I tried to actually map the nested list somehow, like this:
CreateMap<User, UserWebDtoWithQuotas>()
.ConstructUsing((user, context) =>
{
var quotas = context.Mapper.Map<List<UserQuotaWebDto>>(user.Quotas);
return new UserWebDtoWithQuotas(user.Id, user.Username, quotas);
});
And it throws the same "no default constructor" again.
What am I doing wrong? Is it at all possible to make complex custom rules for constructing objects?
答案1
得分: 1
以下是您提供的代码的翻译部分:
UserQuota.cs
public record UserQuota
{
public string quotaA { get; set; }
public string quotaB { get; set; }
}
UserQuotaWebDto.cs
public record UserQuotaWebDto
{
public string quotaA { get; set; }
public string quotaB { get; set; }
}
User.cs
public record User
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuota> Quotas { get; private init; }
public User(Guid userId, string username, List<UserQuota> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
UserWebDtoWithQuotas.cs
public record UserWebDtoWithQuotas
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuotaWebDto> Quotas { get; private init; }
public UserWebDtoWithQuotas(Guid userId, string username, List<UserQuotaWebDto> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
test controller
[HttpGet("test")]
public void test()
{
MapperConfiguration configuration = new MapperConfiguration(cfg =>
{
// TestA -> TestB
cfg.CreateMap<UserQuota, UserQuotaWebDto>();
cfg.CreateMap<User, UserWebDtoWithQuotas>();
});
IMapper mapper = configuration.CreateMapper();
User user1 = new User(Guid.NewGuid(), "Tom", new List<UserQuota>() { new UserQuota() { quotaA = "qA1", quotaB = "qB1" }, new UserQuota() { quotaA = "qA2", quotaB = "qB2" } });
UserWebDtoWithQuotas user2 = mapper.Map<UserWebDtoWithQuotas>(user1);
Console.WriteLine("user1:" + JsonConvert.SerializeObject(user1));
Console.WriteLine("user2:" + JsonConvert.SerializeObject(user2));
}
英文:
You can try the following code.<br>
UserQuota.cs
public record UserQuota
{
public string quotaA { get; set; }
public string quotaB { get; set; }
}
UserQuotaWebDto.cs
public record UserQuotaWebDto
{
public string quotaA { get; set; }
public string quotaB { get; set; }
}
User.cs
public record User
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuota> Quotas { get; private init; }
public User(Guid userId, string username, List<UserQuota> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
UserWebDtoWithQuotas.cs
public record UserWebDtoWithQuotas
{
public Guid UserId { get; private init; }
public string Username { get; private init; }
public List<UserQuotaWebDto> Quotas { get; private init; }
public UserWebDtoWithQuotas(Guid userId, string username, List<UserQuotaWebDto> quotas)
{
UserId = userId;
Username = username;
Quotas = quotas;
}
}
test controller
[HttpGet("test")]
public void test()
{
MapperConfiguration configuration = new MapperConfiguration(cfg =>
{
// TestA -> TestB
cfg.CreateMap<UserQuota, UserQuotaWebDto>();
cfg.CreateMap<User, UserWebDtoWithQuotas>();
});
IMapper mapper = configuration.CreateMapper();
User user1 = new User(Guid.NewGuid(), "Tom", new List<UserQuota>() { new UserQuota() { quotaA = "qA1", quotaB = "qB1" }, new UserQuota() { quotaA = "qA2", quotaB = "qB2" } });
UserWebDtoWithQuotas user2 = mapper.Map<UserWebDtoWithQuotas>(user1);
Console.WriteLine("user1:"+JsonConvert.SerializeObject(user1));
Console.WriteLine("user2:"+JsonConvert.SerializeObject(user2));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论