繁体   English   中英

使用AutoMapper使用派生对象而不是父对象的映射

[英]Use AutoMapper to use map of derived object instead of parent object

我无法使用AutoMapper找到解决问题的方法,也找不到合适的关键字来在线查找解决方案,因此该问题的标题可能不好,这是我的问题:

我想强迫AutoMapper使用两个有效地图中的一个地图。 这是一个例子:

public class A
{
    public B B { get; set; }
}

public class ADTO
{
    public BDTO B { get; set; }
}

public class B
{
}

public class BDTO
{
}

public class CDTO : BDTO
{
}

public class AProfile : Profile
{
    public AProfile()
    {
        Mapper.CreateMap<B, BDTO>();
        Mapper.CreateMap<B, CDTO>();

        // Is there a way to force AutoMapper to use B to CDTO instead of B to BDTO ?
        Mapper.CreateMap<A, ADTO>()
            .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B));
    }
}

如果我删除以下行,则AutoMapper会引发错误,指出它无法在A到ADTO映射中为B属性找到有效的映射。

Mapper.CreateMap<B, BDTO>();

有什么方法可以使我的地图B到CDTO有效吗?

卢西安答案的编辑

所以我想一种解决方案是使它成为两个步骤:

var a = new A { B = new B() }
var adto = new ADTO();

adto = Mapper.Map(a, adto); // Map B to BDTO
adto.B = Mapper.Map<CDTO>(a.B); // Change BDTO to CDTO

我更喜欢一种合适的解决方案:

var a = new A { B = new B() }
var adto = new ADTO();

adto = Mapper.Map(a, adto); // Map directly B to CDTO

有什么办法可以实现?

来自Lucian的EDIT 2再次回答

事实是,A和B是来自EF的实体,由于我使用.ProjectTo扩展名,因此我无权访问ADTO初始化。

我的代码更像是:

var adto = db.As.ProjectTo<ADTO>().ToList();

其中db是我DbContextAsDbSetA

来自Lucian的EDIT 3再次回答

我不知道那个ConstructProjectionUsing方法,谢谢! 在这里,我设法用您的答案构建代码。

Mapper.CreateMap<A, ADTO>()
   .ConstructProjectionUsing(a => new ADTO() { B = new CDTO() })
   .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B));

那太好了! 但是现在,我还有另一个问题,B和BDTO实际上是ICollection和IEnumerable ...我不认为这会是一个问题,所以我没有告诉。 这里是更新的代码:

public class A
{
    public ICollection<B> B { get; set; }
}

public class ADTO
{
    public IEnumerable<BDTO> B { get; set; }
}

所以我认为我不能使用ConstructProjectionUsing,因为此代码无法编译:

Mapper.CreateMap<A, ADTO>()
   .ConstructProjectionUsing(a => new ADTO() { B = new List<CDTO>() }) // Error here, can't convert List<CDTO> to List<BDTO> 
   .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B));

我想我被困在这里了吗?

您可以使用CDTO实例初始化ADTO.B并映射到现有对象。

var a = new A { B = new B() };  
var adto = new ADTO { B = new CDTO() };  
Mapper.Map(a, adto); // Map directly B to CDTO

这将适用于较新的AM。 您可能需要将UseDestinationValue和旧的一起使用。

对于构造,可以使用ConstructProjectionUsing。 一个例子 但是否则,我认为您需要在目的地中输入正确的类型。

好的,按原样,您可以重定向地图。 它似乎可以与ProjectTo一起使用。 这里

 Mapper.CreateMap<B, BDTO>().As<CDTO>();

当然,这适用于所有地方,不仅适用于ProjectTo。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM