我无法使用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有效?
来自Lucian回复的编辑
所以我想一个解决方案就是分两步:
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
DbContext
As
DbSet
A
Mapper.CreateMap<A, ADTO>()
.ConstructProjectionUsing(a => new ADTO() { B = new CDTO() })
.ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B));
。{/ p>
来自Lucian的EDIT 3再次回答
我不知道那个ConstructProjectionUsing方法,谢谢!这是我用你的答案建立的代码。
public class A
{
public ICollection<B> B { get; set; }
}
public class ADTO
{
public IEnumerable<BDTO> B { get; set; }
}
这就是明智的!但是现在,我还有另外一个问题,B和BDTO实际上是ICollection和IEnumerable ......我不认为这将是一个问题,所以我没有告诉。这里更新了代码:
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));
所以我认为我不能使用ConstructProjectionUsing,因为这段代码不会编译:
Object{ 2017-08-01:Array(2), 2017-08-02:Array(1) }
我想我会被困在这里?
答案 0 :(得分:1)
您可以使用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与旧版本一起使用。
答案 1 :(得分:1)
对于构造,您可以使用ConstructProjectionUsing。 An example。但除此之外,我认为您需要在目的地中使用正确的类型。
答案 2 :(得分:1)
好的,所以这是允许你重定向地图的原因。它似乎与ProjectTo一起使用。请参阅here。
Mapper.CreateMap<B, BDTO>().As<CDTO>();
当然这适用于所有地方,不仅适用于ProjectTo。