首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用自动映射器将一个源类映射到多个派生类

使用自动映射器将一个源类映射到多个派生类
EN

Stack Overflow用户
提问于 2013-02-05 18:16:39
回答 3查看 26.6K关注 0票数 34

假设我有一个源类:

代码语言:javascript
复制
public class Source
{
    //Several properties that can be mapped to DerivedBase and its subclasses
}

和一些目标类:

代码语言:javascript
复制
public class DestinationBase
{
     //Several properties
}

public class DestinationDerived1 : DestinationBase
{
     //Several properties
}

public class DestinationDerived2 : DestinationBase
{
     //Several properties
}

然后我希望派生的目标类继承基类的自动映射器配置,因为我不想重复它,有什么方法可以实现吗?

代码语言:javascript
复制
Mapper.CreateMap<Source, DestinationBase>()
    .ForMember(...)
    // Many more specific configurations that should not have to be repeated for the derived classes
    .ForMember(...);

Mapper.CreateMap<Source, DestinationDerived1 >()
    .ForMember(...);
Mapper.CreateMap<Source, DestinationDerived2 >()
    .ForMember(...);

当我这样写它时,它根本不使用基映射,而include似乎对我没有帮助。

编辑:这是我得到的:

代码语言:javascript
复制
public class Source
{
    public string Test { get; set; }
    public string Test2 { get; set; }
}

public class DestinationBase
{
    public string Test3 { get; set; }
}

public class DestinationDerived1 : DestinationBase
{
    public string Test4 { get; set; }
}

public class DestinationDerived2 : DestinationBase
{
    public string Test5 { get; set; }
}

代码语言:javascript
复制
Mapper.CreateMap<Source, DestinationBase>()
              .ForMember(d => d.Test3, e => e.MapFrom(s => s.Test))
              .Include<Source, DestinationDerived1>()
              .Include<Source, DestinationDerived2>();

        Mapper.CreateMap<Source, DestinationDerived1>()
              .ForMember(d => d.Test4, e => e.MapFrom(s => s.Test2));

        Mapper.CreateMap<Source, DestinationDerived2>()
              .ForMember(d => d.Test5, e => e.MapFrom(s => s.Test2));

AutoMapper.AutoMapperConfigurationException :找到了未映射的成员。查看下面的类型和成员。

添加自定义映射表达式、忽略、添加自定义解析器或修改源/目标类型

源-> DestinationDerived1 (目标成员列表)

Test3

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-05 18:23:29

将派生映射包含到基本映射中:

代码语言:javascript
复制
Mapper.CreateMap<Source, DestinationBase>()
    .ForMember(d => d.Id, op => op.MapFrom(s => s.Id)) // you can remove this
    .Include<Source, DestinationDerived1>()
    .Include<Source, DestinationDerived2>();

Mapper.CreateMap<Source, DestinationDerived1>()
    .ForMember(d => d.Name, op => op.MapFrom(s => s.Text))
    .ForMember(d => d.Value2, op => op.MapFrom(s => s.Amount));

Mapper.CreateMap<Source, DestinationDerived2>()
    .ForMember(d => d.Value, op => op.MapFrom(s => s.Amount));

用法:

代码语言:javascript
复制
Mapper.AssertConfigurationIsValid();
var s = new Source() { Id = 2, Amount = 10M, Text = "foo" };
var d1 = Mapper.Map<DestinationDerived1>(s);
var d2 = Mapper.Map<DestinationDerived2>(s);

请参阅AutoMapper维基上的Mapping inheritance

更新:下面是类的完整代码,可以正常工作。

代码语言:javascript
复制
public class Source
{
    public int Id { get; set; }
    public string Text { get; set; }
    public decimal Amount { get; set; }
}

public class DestinationBase
{
    public int Id { get; set; }
}

public class DestinationDerived1 : DestinationBase
{
    public string Name { get; set; }
    public decimal Value2 { get; set; }
}

public class DestinationDerived2 : DestinationBase
{
    public decimal Value { get; set; }
}

更新( AutoMapper错误的解决方法):

代码语言:javascript
复制
public static class Extensions
{
    public static IMappingExpression<Source, TDestination> MapBase<TDestination>(
        this IMappingExpression<Source, TDestination> mapping)
        where TDestination: DestinationBase
    {
        // all base class mappings goes here
        return mapping.ForMember(d => d.Test3, e => e.MapFrom(s => s.Test));
    }
}

和所有映射:

代码语言:javascript
复制
    Mapper.CreateMap<Source, DestinationBase>()
          .Include<Source, DestinationDerived1>()
          .Include<Source, DestinationDerived2>()
          .MapBase();

    Mapper.CreateMap<Source, DestinationDerived1>()
          .MapBase()
          .ForMember(d => d.Test4, e => e.MapFrom(s => s.Test2));

    Mapper.CreateMap<Source, DestinationDerived2>()
          .MapBase()
          .ForMember(d => d.Test5, e => e.MapFrom(s => s.Test2));
票数 25
EN

Stack Overflow用户

发布于 2019-04-18 22:05:16

用于自动映射程序8.0的

当前版本有新的方法IncludeAllDerived

以下是工作示例:

代码语言:javascript
复制
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Source, DestinationBase>()
                .ForMember(dest => dest.Test3, opt => opt.MapFrom(src => src.Test))
                .IncludeAllDerived();

            cfg.CreateMap<Source, DestinationDerived1>()
                .ForMember(dest => dest.Test4, opt => opt.MapFrom(src => src.Test2));

            cfg.CreateMap<Source, DestinationDerived2>()
                  .ForMember(dest => dest.Test5, opt => opt.MapFrom(src => src.Test2));
        });

        var mapper = config.CreateMapper();

        var source = new Source { Test = "SourceTestProperty", Test2 = "SourceTest2Property" };
        var d1 = mapper.Map<DestinationDerived1>(source);
        var d2 = mapper.Map<DestinationDerived2>(source);

        Assert.Equal("SourceTestProperty", d1.Test3);
        Assert.Equal("SourceTest2Property", d1.Test4);

        Assert.Equal("SourceTestProperty", d2.Test3);
        Assert.Equal("SourceTest2Property", d2.Test5);
票数 5
EN

Stack Overflow用户

发布于 2019-09-06 18:57:04

注意!适用于那些在派生接口方面有问题的人。AutoMapper不支持向派生接口注册。只处理类。

要使其正常工作,您必须将CreateMap的类型引用更改为类而不是接口。

示例:

代码语言:javascript
复制
interface Interface1 {}
class Class1: Interface1 {}
interface Interface2: Interface1 {}
class Class2: Class1, Interface2 {}

CreateMap<OtherClass, Interface1>().IncludeAllDerived();
CreateMap<OtherClass, Interface2>();

任何针对Interface2的映射都将只使用第一个CreateMap。您必须将第二个标识为

代码语言:javascript
复制
CreateMap<OtherClass, Class2>();
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14705064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档