C# 使用AutoMapper可以使用派生对象的贴图而不是父对象

C# 使用AutoMapper可以使用派生对象的贴图而不是父对象,c#,inheritance,automapper,C#,Inheritance,Automapper,我无法使用AutoMapper找到问题的解决方案,也无法在网上找到正确的关键字来找到解决方案,因此该问题的标题可能不好,以下是我的问题: 我想强制AutoMapper使用两个有效映射中的一个映射。这里有一个例子: public class A { public B B { get; set; } } public class ADTO { public BDTO B { get; set; } } public class B { } public class BDTO {

我无法使用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));
    }
}
有什么办法让它发生吗

再次编辑Lucian answer中的2

事实上,A和B是来自EF的实体,在使用.ProjectTo扩展时,我没有访问ADTO初始化的权限

我的代码更像:

var adto = db.As.ProjectTo<ADTO>().ToList();
这太棒了!但现在,我有另一个问题,B和BDTO实际上是ICollection和IEnumerable。。。我认为这不会是一个问题,所以我没有告诉你。更新代码如下:

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

public class ADTO
{
    public IEnumerable<BDTO> B { get; set; }
}
公共A类
{
公共ICollection B{get;set;}
}
公共类广告
{
公共IEnumerable B{get;set;}
}
因此,我认为我不能使用ConstructionProjectionUsing,因为这段代码无法编译:

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));
Mapper.CreateMap()
.ConstructProjectionUsing(a=>new ADTO(){B=new List()})//此处出错,无法将列表转换为列表
.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用于旧的对象。

您可以使用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与旧版本一起使用。

对于构造,您可以使用ConstructionProjectionUsing。但除此之外,我认为您需要在目标中使用正确的类型。

对于构造,您可以使用ConstructionProjectionUsing。但除此之外,我认为您需要在目的地中输入正确的类型。

好的,这样您就可以重定向地图。它似乎与ProjectTo一起工作。看

Mapper.CreateMap().As();

当然,这不仅适用于ProjectTo,而且适用于任何地方。

好的,这也是允许重定向地图的原因。它似乎与ProjectTo一起工作。看

Mapper.CreateMap().As();

当然,这不仅适用于ProjectTo,而且适用于任何地方。

谢谢你的回答,我更新了我的帖子,并提供了你的建议。实际上,这可能适用于此场景,但我无法使用.ProjectTo扩展方法访问ADTO初始化。A和B是来自EF的实体。让我再次更新我的帖子。谢谢你的回答,我用你的建议更新了我的帖子。这个场景可能真的可以使用,但我无法使用.ProjectTo扩展方法访问ADTO初始化。A和B是来自EF的实体。让我再次更新我的帖子。好吧,你再次为我暴露的问题提供了一个正确的答案,这对我的真实情况不起作用。。。让我再次更新我的帖子。好吧,你再次为我暴露的问题提供了一个正确的答案,这对我的真实情况不起作用。。。让我再一次更新我的帖子。就是这样,像个魔术师一样工作。真的谢谢你,卢西恩,就这样,好好工作。真的谢谢你,卢西恩。
public class A
{
    public ICollection<B> B { get; set; }
}

public class ADTO
{
    public IEnumerable<BDTO> B { get; set; }
}
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));
var a = new A { B = new B() };  
var adto = new ADTO { B = new CDTO() };  
Mapper.Map(a, adto); // Map directly B to CDTO
 Mapper.CreateMap<B, BDTO>().As<CDTO>();