我有以下场景 我有以下 c# 类
public class ApiRequest{
public int? FwVersion { get; set; }
public int? OsVersion { get; set; }
public int PageSize { get; set; }
public string Owner { get; set; } = String.Empty;
}
和
public class DbRequest {
public int PageSize { get; set; }
public string Owner { get; set; } = String.Empty;
public int FwVersion { get; set; }
public bool FwVersionSpecified { get; set; }
public int OsVersion { get; set; }
public bool OsVersionSpecified { get; set; }
}
现在我将对象从 ApiRequest 转换为 DbRequest。我必须这样做的方法如下
对于我的
ApiRequest
中的每个可空属性,DbRequest
类中都有一个不可为空的属性,以及具有相同名称和“SpecifiedSuffix”的其他布尔属性。我使用 GetValueOrDefault()
填充不可为 null 的属性,并使用 HasValue
填充适当的指定属性。这是我的 AutoMapper 配置的示例:
public class MappingConfiguration : Profile
{
public MappingConfiguration()
{
// Fix mappings
CreateMap<ApiRequest, DbRequest>()
.ForMember(dst => dst.FwVersion, opt => opt.MapFrom(
src => src.FwVersion.GetValueOrDefault()
))
.ForMember(dst => dst.FwVersionSpecified, opt => opt.MapFrom(
src => src.FwVersion.HasValue
))
.ForMember(dst => dst.OsVersion, opt => opt.MapFrom(src => src.OsVersion.GetValueOrDefault()))
.ForMember(dst => dst.OsVersionSpecified, opt => opt.MapFrom(src => src.OsVersion.HasValue));
}
}
这有效。然而我的问题是我有其他类,如 ApiRequest / DbRequest,它们有很多可为空和指定的属性。有没有一种更简单的方法来映射它们,而无需手动逐一字段?
根据您的场景实现两种方法:
方法1
对于以“Specified”为后缀的目标成员,必须实现带有
ForMember()
的映射规则。对于其余成员,仅当源成员不为 null 时,才可以使用 ForAllMembers()
来映射成员。
CreateMap<ApiRequest, DbRequest>()
.ForMember(dst => dst.FwVersionSpecified, opt => opt.MapFrom(
src => src.FwVersion.HasValue
))
.ForMember(dst => dst.OsVersionSpecified, opt => opt.MapFrom(src => src.OsVersion.HasValue))
.ForAllMembers(o => o.Condition((src, dest, value) => value != null));
方法2
如果您认为方法 1 不够好,您可以查找 System.Reflection 并处理带/不带“指定”后缀的目标成员的场景。
using System.Reflection;
CreateMap<ApiRequest, DbRequest>()
.ForAllMembers(o => o.MapFrom((src, dest, value) =>
{
string specified = "Specified";
bool isSpecified = o.DestinationMember.Name.EndsWith(specified);
if (isSpecified)
{
PropertyInfo prop = typeof(ApiRequest).GetProperty(o.DestinationMember.Name[0..^specified.Length]);
return prop.GetValue(src) != null;
}
else
{
PropertyInfo prop = typeof(ApiRequest).GetProperty(o.DestinationMember.Name);
return prop.GetValue(src) ?? default;
}
}));