c# - 在 Entity Framework Core 中将字典转换为 ICollection
问题描述
在这里,我被EF Core中的dictionary
to转换困住了。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; }
}
public async Task<LastPayCertificateViewModel> Handle(LastPayCertificateQuery request, CancellationToken cancellationToken)
{
var predicate = PredicateBuilder.False<FlatEmployee>();
predicate = predicate.Or(emp => emp.EmployeeId == request.EmployeeCode);
var employee = await _context.FlatEmployee
.Where(predicate)
.FirstOrDefaultAsync(cancellationToken);
if (employee == null)
return null;
var empVM = _mapper.Map<LastPayCertificateViewModel>(employee);
}
然后我在PayAndAllowances in empVM
. 这就是我的问题所在。我的问题在哪里?我认为这是因为 Dictionary 具有键值对并且无法转换为BaseEmployeeDictionary
. 我也尝试过这种方式将列表项添加到PayAndAllowances in empVM
foreach (KeyValuePair<string, long> data in employee.DeductionsByAdjustment)
{
BaseEmployeeDictionary listItem = new BaseEmployeeDictionary
{
Name = data.Key,
Amount = data.Value
};
empVM.EarningDetails.PayAndAllowances.Add(listItem);
return empVM;
}
这当然不会起作用,因为它empVM.EarningDetails.PayAndAllowances
是 null 并抛出 NullReferenceException。我的疑问是如何在创建地图时在字典和 ICollection 之间进行映射EmployeeEarningDTO
。或者,如果您提出宝贵的建议和解决方案,我们将不胜感激。
解决方案
原来是 AutoMapper 映射问题。
首先,与相比, EmployeeEarningDTO
inside创建了额外的级别:LastPayCertificateViewModel
FlatEmployee
LastPayCertificateViewModel.PayPayAndAllowances.PayAndAllowances
对比
FlatEmployee.PayAndAllowances
AutoMapper 默认映射同名的属性。所以在里面FlatEmployee
映射LastPayCertificateViewModel
它会尝试映射Dictionary<string, long> PayAndAllowances
到EmployeeEarningDTO PayAndAllowances
. 但是没有从Dictionary<string, long>
到的映射EmployeeEarningDTO
。相反,有一个从FlatEmployee
to的映射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 FlatEmployee
to 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 })));
推荐阅读
- azure - 为什么通过内存流上传 JSON 时 BlobClient.UploadAsync 会挂起?
- javascript - data.map 函数在第二次调用后停止工作
- r - tidyr 1.1.0 中的 unnest 错误错误:无法分配大小为 1024 Kb 的向量
- python - 文件对象本身包含什么?
- javascript - 带有 ===、returnaspromise 和类对象的 Angular Guidance
- c# - 我尝试将一个巨大的 csv 文件导入我的 wpf 应用程序,但导入后出现数组错误 System.IndexOutOfRangeException
- android - 为属性“adb Exe”指定的不存在(react-native)
- css - Chrome 显示高度有限的 PDF
- java - 如何在弹性搜索中创建索引,以便每天上传数据时创建一个带有日期的新索引别名并允许我删除它们
- android - 在飞行模式下发送多个远程推送通知,重新连接时只收到最后一个