AutoMapper:在映射期间忽略特定的字典项

Roh*_*ner 5 c# enums automapper

语境:

有两个主要类看起来像这样:

public class Source
{
   public Dictionary<AttributeType, object> Attributes { get; set; }
}

public class Target
{
   public string Title { get; set; }
   public string Description { get; set; }
   public List<Attribute> Attributes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

sub/collection/Enum类型:

public class Attribute
{
   public string Name { get; set; }
   public string Value { get; set; }
}

public enum AttributeType
{
    Title,
    Description,
    SomethingElse,
    Foobar
}
Run Code Online (Sandbox Code Playgroud)

目前我的地图看起来像这样:

 CreateMap<Source, Target>()
  .ForMember(dest => dest.Description, opt => opt.MapAttribute(AttributeType.Description))
  .ForMember(dest => dest.Title, opt => opt.MapAttribute(AttributeType.Title));
Run Code Online (Sandbox Code Playgroud)

在哪里MapAttribute获取项目Dictionary并使用AttributeType我提供的项目,将其作为(名称和值)对象添加到目标集合中(如果密钥不存在,则使用try get并返回空)...

完成所有这些后,我的目标设置结束了如下:

{ 
  title: "Foo", 
  attributes: [
     { name: "SomethingElse", value: "Bar" }, 
     { name: "Title", value: "Foo"}
  ] 
}
Run Code Online (Sandbox Code Playgroud)


题:

如何将其余项目映射到目标类,但我需要能够排除特定键(如标题或描述).EG Source.Attribute在Target中具有已定义位置的项目将从Target.Attributes集合中排除,"left-over"属性仍将转到Target.Attributes.

为了更清晰(如果我的源代码如下):

{ attributes: { title: "Foo", somethingelse: "Bar" } }
Run Code Online (Sandbox Code Playgroud)

它会映射到这样的目标:

{ title: "Foo", attributes: [{ name: "SomethingElse", value: "Bar" }] }
Run Code Online (Sandbox Code Playgroud)

我试过这个,但它没有编译,说明如下:

仅对类型上的顶级单个成员支持成员的自定义配置.

CreateMap<KeyValuePair<AttributeType, object>, Attribute>()
   .ForSourceMember(x => x.Key == AttributeType.CompanyName, y => y.Ignore())
Run Code Online (Sandbox Code Playgroud)

ASp*_*rin 3

可以对映射配置上的值进行预过滤,某些值甚至不会到达我正在使用 automapper v6.1.1的目标,存在一些差异,但想法应该是相同的)

为了使事情正常工作,我必须首先添加KeyValuePair<AttributeType, object>到映射(仅返回字典值)AttributeMapAttribute

CreateMap<KeyValuePair<AttributeType, object>, Attribute>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(s => s.Key))
    .ForMember(dest => dest.Value, opt => opt.MapFrom(s => s.Value));
Run Code Online (Sandbox Code Playgroud)

当定义了哪些属性应该被忽略时,它们将进入忽略列表,根据该映射将过滤掉多余的属性

var ignoreAttributes = new[] {AttributeType.Description, AttributeType.Title};
CreateMap<Source, Target>()
    .ForMember(dest => dest.Description, opt => opt.MapFrom(s => s.MapAttribute(AttributeType.Description)))
    .ForMember(dest => dest.Title, opt => opt.MapFrom(s => s.MapAttribute(AttributeType.Title)))
    .ForMember(dest=>dest.Attributes, opt=> opt.MapFrom(s=>s.Attributes
        .Where(x=> !ignoreAttributes.Contains(x.Key))));
Run Code Online (Sandbox Code Playgroud)

基于最终的映射示例

var result = Mapper.Map<Target>(new Source
{
    Attributes = new Dictionary<AttributeType, object>
    {
        {AttributeType.Description, "Description"},
        {AttributeType.Title, "Title"},
        {AttributeType.SomethingElse, "Other"},
    }
});
Run Code Online (Sandbox Code Playgroud)

结果将填充标题、描述和一个属性 SomethingElse

在此输入图像描述 在此输入图像描述