为了账号安全,请及时绑定邮箱和手机立即绑定

在 Entity Framework Core 中将字典转换为 ICollection

在 Entity Framework Core 中将字典转换为 ICollection

C#
守着星空守着你 2022-12-24 13:37:41
在这里,我对EF Core中的dictionaryto转换感到困惑。Icollection我Dictionary在FlatEmployee课堂上将键值对列表存储在数据库中。我这样声明:public class FlatEmployee{    public int EmployeeId { get; set; }    public Dictionary<string, long> PayAndAllowances { get; set; }}//====================Configuration public void Configure(EntityTypeBuilder<FlatEmployee> builder){        builder.HasKey(f => new { f.EmployeeId });        builder.Property(sb => sb.PayAndAllowances)            .HasConversion(                pa => JsonConvert.SerializeObject(pa),                pa => JsonConvert.DeserializeObject<Dictionary<string, long>>(pa));}当我播种或插入时,这绝对没问题。但是我在尝试获取 FlatEmployee 类时遇到的问题。这是因为我想获取 Collection 中的字典。为此,我声明了另一个这样的类:public class LastPayCertificateViewModel: IHaveCustomMapping{    public int EmployeeCode { get; set; }    public EmployeeEarningDTO PayAndAllowances { get; set; }    public void CreateMappings(Profile configuration)    {        configuration.CreateMap<FlatEmployee, LastPayCertificateViewModel>()            .ForMember(dto => dto.EmployeeCode , opt => opt.MapFrom(entity => entity.EmployeeId ));    }}public class EmployeeEarningDTO : IHaveCustomMapping{    public ICollection<BaseEmployeeDictionary> PayAndAllowances { get; set; }    public void CreateMappings(Profile configuration)    {        configuration.CreateMap<FlatEmployee, EmployeeEarningDTO>()            .ForMember(dto => dto.PayAndAllowances, opt => opt.MapFrom(entity => entity.PayAndAllowances));    }}public class BaseEmployeeDictionary{    public string Name { get; set; }    public long Amount { get; set; }}当我尝试使用上面的类来获取这样的数据时:public class LastPayCertificateQuery : IRequest<LastPayCertificateViewModel>{    public string EmployeeCode { get; set; }}
查看完整描述

1 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

原来是AutoMapper映射问题。


首先,与以下相比,EmployeeEarningDTO内部创建了额外的级别:LastPayCertificateViewModelFlatEmployee


LastPayCertificateViewModel.PayPayAndAllowances.PayAndAllowances

对比


FlatEmployee.PayAndAllowances

AutoMapper 默认映射具有相同名称的属性。所以在FlatEmployeemap内部LastPayCertificateViewModel它会尝试映射Dictionary<string, long> PayAndAllowances到EmployeeEarningDTO PayAndAllowances. 但是没有从Dictionary<string, long>到的映射EmployeeEarningDTO。相反,有一个从FlatEmployee到的映射EmployeeEarningDTO,所以你必须告诉 AM 使用它:


configuration.CreateMap<FlatEmployee, LastPayCertificateViewModel>()

    .ForMember(dto => dto.EmployeeCode, opt => opt.MapFrom(entity => entity.EmployeeId))

    .ForMember(dto => dto.PayAndAllowances, opt => opt.MapFrom(entity => entity)); // <--

其次,映射 from FlatEmployeeto EmployeeEarningDTO- AM 会自动尝试映射PayAndAllowances属性,但是没有映射 from KeyValuePair<string, long>to BaseEmployeeDictionary。你可以定义这样的映射


configuration.CreateMap<KeyValuePair<string, long>, BaseEmployeeDictionary>()

                        .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.Key))

                        .ForMember(dst => dst.Amount, opt => opt.MapFrom(src => src.Value));

这将使您可以简单地使用


configuration.CreateMap<FlatEmployee, EmployeeEarningDTO>();

但是您可能不会这样做,因为您不希望每个都 KeyValuePair<string, long>映射到BaseEmployeeDictionary,因此您可以就地进行映射:


configuration.CreateMap<FlatEmployee, EmployeeEarningDTO>()

     .ForMember(dto => dto.PayAndAllowances, opt => opt.MapFrom(entity => entity.PayAndAllowances

        .Select(src => new BaseEmployeeDictionary { Name = src.Key, Amount = src.Value })));



查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 139 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信