Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 根据ob属性值确定要映射到的类型_C#_Automapper - Fatal编程技术网

C# 根据ob属性值确定要映射到的类型

C# 根据ob属性值确定要映射到的类型,c#,automapper,C#,Automapper,通常,您将Automapper配置为从类型A映射到类型B。我需要Automapper映射到类型B或类型C,具体取决于类型A中的属性值。我还需要从类型B或类型C映射回类型A 目前提出的解决方案是定义两种类型的映射(A=>B,A=>C),并根据鉴别器在自定义if/switch构造中调用正确的映射。映射嵌套类型时,此解决方案不起作用,因为此时将调用高级映射。 例如,根据动物的AnimalType值,type Animal映射到猫或狗 我还需要从猫或狗返回的方法,这应该很简单,因为在这里我可以定义2个固

通常,您将Automapper配置为从类型A映射到类型B。我需要Automapper映射到类型B或类型C,具体取决于类型A中的属性值。我还需要从类型B或类型C映射回类型A

目前提出的解决方案是定义两种类型的映射(A=>B,A=>C),并根据鉴别器在自定义if/switch构造中调用正确的映射。映射嵌套类型时,此解决方案不起作用,因为此时将调用高级映射。

例如,根据动物的AnimalType值,type Animal映射到猫或狗

我还需要从猫或狗返回的方法,这应该很简单,因为在这里我可以定义2个固定的关系(狗=>animal,猫=>animal)

是否可以定义映射动物=>狗或猫?如果是,怎么做

    public enum EAnimalType
    {
        Cat = 1,
        Dog = 2
    }

    public class Animal
    {
        public EAnimalType AnimalType { get; set; }

        public int Age { get; set; }
    }

    public abstract class AnimalDto
    {
        public int Age { get; set; }
    }

    public class CatDto : AnimalDto {}

    public class DogDto : AnimalDto {}

使用类型转换器,可以从a映射到b或c。这是可行的,因为在类型转换器中,我自己定义映射指令。收回:映射是手动定义的,如果将属性添加到类中,则必须更新映射

也许存在更好的解决方案

    [TestMethod]
    public void VerifyMappingsSecuritiesModule()
    {
        // Arrange
        Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Animal, AnimalDto>().ConvertUsing<TypeTypeConverter>();
            });

        var expectedAge = 10;
        var animal = new Animal { Age = expectedAge, AnimalType = EAnimalType.Cat };

        // Act
        var catDto = Mapper.Map<Animal, AnimalDto>(animal);

        // Assert
        Assert.IsInstanceOfType(catDto, typeof(CatDto));
        Assert.AreEqual(expectedAge, catDto.Age);
    }

    public class TypeTypeConverter : ITypeConverter<Animal, AnimalDto>
    {
        public AnimalDto Convert(ResolutionContext context)
        {
            var animal = (Animal)context.SourceValue;

            if (animal.AnimalType == EAnimalType.Cat) { return new CatDto { Age = animal.Age }; }
            else { return new DogDto { Age = animal.Age };  }
        }
    }
[TestMethod]
public void VerifyMappingsSecuritiesModule()
{
//安排
Mapper.Initialize(cfg=>
{
CreateMap().ConvertUsing();
});
var expectedAge=10;
var animal=新动物{年龄=预期年龄,动物类型=EAnimalType.Cat};
//表演
var catDto=Mapper.Map(动物);
//断言
IsInstanceOfType(catDto,typeof(catDto));
Assert.AreEqual(预期年龄、catDto.Age);
}
公共类TypeConverter:ITypeConverter
{
要转换的公共动物(ResolutionContext上下文)
{
var animal=(animal)context.SourceValue;
如果(animal.AnimalType==EAnimalType.Cat){返回新的CatDto{Age=animal.Age};}
else{将新狗返回到{Age=animal.Age};}
}
}

在基本类型上定义映射。此映射使用
ConstructUsing
通过调用适用的子映射来实例化正确的子DTO。使用AutoMapper 3.0进行测试

CreateMap<Animal, AnimalDto>()
      // create DTO by dispatching to child type mappings
      .ConstructUsing((animal, context) => {
           switch (animal.AnimalType) {
               case EAnimalType.Dog:
                   return context.Mapper.Map<DogDto>(animal);
               case EAnimalType.Cat:
                   return context.Mapper.Map<CatDto>(animal);
               default:
                   throw new NotSupportedException(
                       $"Animal Type '{animal.AnimalType}' is not supported."
                   );
           }       
       })
      // map members of base type
      .ForMember(dto => dto.Age, o => o.MapFrom(ent => ent.Age));

      // mappings for child types, will handle dispatch from base type
      CreateMap<Animal, DogDto>()
           .ForMember(dto => dto.Age, o => o.Ignore()) // already mapped from base type 
           .ForMember(dto => dto.DogSpecific, o => o.MapFrom(dog => dog.DogSpecific));

      CreateMap<Animal, CatDto>()
           .ForMember(dto => dto.Age, o => o.Ignore()); // already mapped from base type
CreateMap()
//通过分派到子类型映射来创建DTO
.ConstructUsing((动物、上下文)=>{
开关(动物。动物类型){
案例EAnimalType.Dog:
返回context.Mapper.Map(动物);
案例EAnimalType.Cat:
返回context.Mapper.Map(动物);
违约:
抛出新的NotSupportedException(
$“不支持动物类型{Animal.AnimalType}。”
);
}       
})
//映射基类型的成员
.ForMember(dto=>dto.Age,o=>o.MapFrom(ent=>ent.Age));
//子类型的映射将处理来自基类型的分派
CreateMap()
.ForMember(dto=>dto.Age,o=>o.Ignore())//已从基类型映射
.ForMember(dto=>dto.DogSpecific,o=>o.MapFrom(dog=>dog.DogSpecific));
CreateMap()
.ForMember(dto=>dto.Age,o=>o.Ignore());//已从基类型映射

为此,映射
Animal,DogDto
Animal,CatDto
必须可由
Animal,AnimalDto
配置中使用的自动映射器访问(例如,在相同的自动映射器配置文件中定义)。

这里的缺点是必须手动映射成员,而不是退回到已定义的映射配置。我想你可以调用
Mapper.Map(动物)
而不是
新狗{Age=animal.Age}。谢谢。我将使用构造函数。我的单元测试也成功了。次要更改:This:CreateMap().ForMember(dto=>dto.Age,o=>o.Ignore())替换为This:CreateMap().IncludeBase();