【发布时间】:2022-08-02 21:55:19
【问题描述】:
我正在使用 Automapper 通过ProjectTo<>() 将数据库实体从实体框架映射到业务对象。现在我想将可空的十进制映射/投影到类类型,并且不想为每个对象中的每个属性指定这两种类型的手动映射,所以我决定使用自定义类型转换器,Automapper 会做工作。当decimal? 属性具有值时,它可以正常工作,但是当它为 null(并且 DB 表列允许 NULL)时,它会抛出一个异常,说“Sql Tree 中的 Null TypeMapping”,并且转换器的 Convert() 方法是根本没有调用。代码如下:
基本类类型和派生(众多之一)
public abstract class BaseUnit
{
public decimal? DefaultValue { get; protected set; }
public abstract ViewableUnit GetRequestedUnit(Unit unit);
}
public class Density : BaseUnit
{
public Density()
{
this.DefaultValue = decimal.Zero;
}
public Density(decimal? densityInGperL)
{
this.DefaultValue = densityInGperL;
}
public decimal? GramsPerLiter
{
get => this.DefaultValue;
set => this.DefaultValue = value;
}
public decimal? GramsPerDeciliter
{
get => this.DefaultValue * 10;
set => this.DefaultValue = value * 0.1m;
}
public override ViewableUnit GetRequestedUnit(Unit unit)
{
...
}
}
转换器和注册
public class DecimalUnitTypeConverter : ITypeConverter<decimal?, Density>
{
public Density Convert(decimal? source, Density destination, ResolutionContext context)
{
return source.HasValue ? new Density(source.Value) : null;
}
}
Mapper.CreateMap(typeof(decimal?), typeof(Density)).ConvertUsing(typeof(DecimalUnitTypeConverter));
数据库实体和 DTO
public class LabResult
{
decimal? NumberResult { get; set; }
...
}
public class LabResultDto
{
Density NumberResult { get; set; }
public void CreateMappings(Profile configuration)
{
configuration.CreateMap<LabResult, LabResultDto>()
.ForMember(
dst => dst.NumberResult,
opt =>
{
opt.PreCondition(src => src.NumberResult.HasValue); // does not have to be here, the outcome is the same
opt.MapFrom(src => src.NumberResult);
});
}
}
和最终用途
dbContext.LabResults.AsNoTracking()
.Where(lab => lab.Id == request.Id)
.ProjectTo<LabResultDto>(this.configurationProvider)
.ToList();
我知道 Map 和 ProjectTo 的工作方式不同,但我认为这种类型的映射/投影是微不足道的,即使我告诉 Automapper 如何通过类型转换器进行操作。我错过了什么吗?感谢您提供任何帮助。
-
好的,我使用了文档但没有检查这部分,我的错。
标签: c# asp.net-core entity-framework-core automapper-11