我有一个有Thing
s集合的课程,可以通过他们的Id
结合他们的ThingCollectionId
来识别。
相应的DtoThing
只包含Id
,我想在将PropertyNotInDto
映射到ThingCollections
时从全球已知的DtoThing
类加载Thing
属性。
这可以通过IMappingAction
到DtoMyClass
映射上的MyClass
来实现,但这需要我重建事物列表并将映射代码添加到MyDtoClass
而不是DtoThing
。
// sources for mapping
public class MyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<Thing, MyClassB> Things {get;set;}
}
public class Thing {
public int Id {get;set;}
// other properties
public string PropertyNotInDto {get;set;}
}
// targets for mapping
public class DtoMyClass {
public Guid ThingCollectionId {get;set;}
public Dictionary<DtoThing, DtoMyClassB> Things {get;set;}
}
public class DtoThing {
public int Id {get;set;}
// no other properties are saved in the DtoThing class
}
// global
public class ThingCollections {
public Dictionary<Guid, List<Thing>> ThingCollections {get;}
}
有没有办法将ThingCollectionId
添加到上下文中,可以在使用DtoThing
到Thing
的映射代码时使用?
我想象的语法看起来像这样:
CreateMap<DtoThing, Thing>().AdvancedMapping<ThingMappingAction>();
ThingMappingAction
可以进入ThingCollectionId
。
我目前的方法如下:
CreateMap<DtoMyClass, MyClass>().AfterMap<MyClassMappingAction>();
...
public MyClassMappingAction : IMappingAction<DtoMyClass, MyClass> {
private ThingCollections ThingCollections {get;}
public MyClassMappingAction(ThingCollections thingCollections){
ThingCollections = thingCollections;
}
public void Process(MyDtoClass source, MyClass target) {
// fix target.Things with ThingCollectionId, Thing.Id and ThingCollections
}
}
但这尤其令人讨厌,因为Thing
用于多个属性,并且每个此类实例都需要特殊代码,需要添加到MyClassMappingAction
。
我通过将ThingCollectionId
添加到BeforeMap
中的上下文并使用ITypeConverter<DtoThing, Thing>
再次访问它来实现此目的。
CreateMap<DtoMyClass, MyClass>().BeforeMap((dto, myclass, context) => context.Items["ThingCollectionId"] = dto.ThingCollectionId);
CreateMap<DtoThing, Thing>().ConvertUsing<ThingTypeConverter>();
public ThingTypeConverter: ITypeConverter<DtoThing, Thing> {
private ThingCollections ThingCollections {get;}
public MyClassMappingAction(ThingCollections thingCollections){
ThingCollections = thingCollections;
}
public Thing Convert(DtoThing source, Thing destination, ResolutionContext context) {
// Get the correct ThingCollection by ThingCollectionId
var thingCollection = ThingCollections[(Guid)context.Items["ThingCollectionId"]];
// Get the correct Thing from the ThingCollection by its Id
return thingCollection.First(t => t.Id == source.Id);
}
}
这取代了先前使用的AfterMap
调用和MyClassMappingAction
。这样,Thing
的映射代码a不包含在MyClass
的映射中,并且不再需要手动重新创建MyClass.Things
字典。