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

在这里,我对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; }

}




守着星空守着你
浏览 150回答 1
1回答

UYOU

原来是AutoMapper映射问题。首先,与以下相比,EmployeeEarningDTO内部创建了额外的级别:LastPayCertificateViewModelFlatEmployeeLastPayCertificateViewModel.PayPayAndAllowances.PayAndAllowances对比FlatEmployee.PayAndAllowancesAutoMapper 默认映射具有相同名称的属性。所以在FlatEmployeemap内部LastPayCertificateViewModel它会尝试映射Dictionary<string, long> PayAndAllowances到EmployeeEarningDTO PayAndAllowances. 但是没有从Dictionary<string, long>到的映射EmployeeEarningDTO。相反,有一个从FlatEmployee到的映射EmployeeEarningDTO,所以你必须告诉 AM 使用它:configuration.CreateMap<FlatEmployee, LastPayCertificateViewModel>()&nbsp; &nbsp; .ForMember(dto => dto.EmployeeCode, opt => opt.MapFrom(entity => entity.EmployeeId))&nbsp; &nbsp; .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>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.Key))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ForMember(dst => dst.Amount, opt => opt.MapFrom(src => src.Value));这将使您可以简单地使用configuration.CreateMap<FlatEmployee, EmployeeEarningDTO>();但是您可能不会这样做,因为您不希望每个都 KeyValuePair<string, long>映射到BaseEmployeeDictionary,因此您可以就地进行映射:configuration.CreateMap<FlatEmployee, EmployeeEarningDTO>()&nbsp; &nbsp; &nbsp;.ForMember(dto => dto.PayAndAllowances, opt => opt.MapFrom(entity => entity.PayAndAllowances&nbsp; &nbsp; &nbsp; &nbsp; .Select(src => new BaseEmployeeDictionary { Name = src.Key, Amount = src.Value })));
打开App,查看更多内容
随时随地看视频慕课网APP