在映射期间添加上下文

问题描述 投票:1回答:1

我有一个有Things集合的课程,可以通过他们的Id结合他们的ThingCollectionId来识别。

相应的DtoThing只包含Id,我想在将PropertyNotInDto映射到ThingCollections时从全球已知的DtoThing类加载Thing属性。

这可以通过IMappingActionDtoMyClass映射上的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添加到上下文中,可以在使用DtoThingThing的映射代码时使用?

我想象的语法看起来像这样:

 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

c# automapper
1个回答
1
投票

我通过将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字典。

© www.soinside.com 2019 - 2024. All rights reserved.