根据具体属性的情况填写属性

问题描述 投票:0回答:1

我有以下场景 我有以下 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,它们有很多可为空和指定的属性。有没有一种更简单的方法来映射它们,而无需手动逐一字段?

c# automapper
1个回答
0
投票

根据您的场景实现两种方法:

方法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;
        }
    }));
© www.soinside.com 2019 - 2024. All rights reserved.