C# 如何在不覆盖值的情况下映射列表
我有一个包含两种不同对象类型的对象,我试图将其映射到另一个包含单个列表的对象 在这个简单的最小可复制示例中,我创建了一个包含动物列表的zoo类,这就是目的地。源代码是MammelHouse类,它包含pig和cow对象的列表 我的问题是,当我尝试将猪添加到列表中时,它会覆盖已经写入的牛。我需要将这两个对象都添加到此列表中 我目前的解决方案是单独映射每个对象类型,然后将它们添加到主对象中,因为我的实际应用程序目前有十种不同的类型,这不是最佳解决方案。我希望有一种方法可以直接用automapper解决这个问题 当前映射尝试C# 如何在不覆盖值的情况下映射列表,c#,automapper,C#,Automapper,我有一个包含两种不同对象类型的对象,我试图将其映射到另一个包含单个列表的对象 在这个简单的最小可复制示例中,我创建了一个包含动物列表的zoo类,这就是目的地。源代码是MammelHouse类,它包含pig和cow对象的列表 我的问题是,当我尝试将猪添加到列表中时,它会覆盖已经写入的牛。我需要将这两个对象都添加到此列表中 我目前的解决方案是单独映射每个对象类型,然后将它们添加到主对象中,因为我的实际应用程序目前有十种不同的类型,这不是最佳解决方案。我希望有一种方法可以直接用automapper解决
将通用的
界面
IMammel
添加到Cow
和Pig
中,然后使用Concat
型号
public interface IMammel
{
}
public class Animal
{
public string Name { get; set; }
}
public class Pig : IMammel
{
public string Species { get; set; } = "pig";
}
public class Cow : IMammel
{
public string Species { get; set; } = "cow";
}
自动映射配置
public class MappingResourceZoo : Profile
{
public MappingResourceZoo()
{
CreateMap<Cow, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
CreateMap<Pig, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
CreateMap<MammalHouse, Zoo>()
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Cows.Concat<IMammel>(src.Pigs)));
}
}
公共类映射资源动物园:配置文件
{
公共地图资源动物园()
{
CreateMap()
.ForMember(dest=>dest.Name,opt=>opt.MapFrom(src=>src.Species));
CreateMap()
.ForMember(dest=>dest.Name,opt=>opt.MapFrom(src=>src.Species));
CreateMap()
.ForMember(dest=>dest.Animals,opt=>opt.MapFrom(src=>src.Cows.Concat(src.Pigs));
}
}
您可以使用AutoMapper准备的扩展Nuget包:它应该处理这样的情况。FormMember(dest=>dest.Animals,opt=>opt.MapFrom(src=>src.Cows.Concat(src.Pigs))
同样MapFrom对于Name
来说也是无用的。动物的第二个MapFrom
简单地覆盖了第一个:)检查。尝试添加concat时出错,这是不允许的。我不知道你能看到执行计划这将是非常有用的谢谢你需要再努力一点:)这是一个非常基本的编译错误。这是你的代码,假设你知道它是否受支持。不幸的是,在现实世界中,动物园和哺乳动物之家是两个来自不同系统的对象模型。我不能改变它们来创建交叉链接concat是不允许的这个问题转移了我的注意力,让我看看为什么它不被允许,看看这是否有帮助,我真的让它工作了谢谢。我能够创建一个IMammel,然后让我做你提到的事情。我将接受这一点,因为它从技术上回答了我提出的问题。。现在看看我是否可以在真实项目中实现它,而不改变顺序模型。感谢您的帮助。我刚刚将IAnimal
添加到Pig
和Cow
而不是Animal
,因此没有交叉链接。也许IMammel
会给出一个清晰的画面。。已使用命名更新答案。。。我以为你无法控制改变这两个系统。
// The Zoo model comes from third party api 1
public class Zoo
{
public List<Animal> Animals { get; set; }
}
public class Animal
{
public string Name { get; set; }
}
// The mammal model comes from third party api Two.
public class MammalHouse
{
public List<Cow> Cows { get; set; }
public List<Pig> Pigs { get; set; }
}
public class Cow
{
public string Species{ get; set; } = "cow";
}
public class Pig
{
public string Species{ get; set; } = "pig";
}
CreateMap<MammalHouse, Zoo>()
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Cows.Concat(src.Pigs)));
opt.MapFrom(src => src.Cows.AddRange(src.Pigs)));
public interface IMammel
{
}
public class Animal
{
public string Name { get; set; }
}
public class Pig : IMammel
{
public string Species { get; set; } = "pig";
}
public class Cow : IMammel
{
public string Species { get; set; } = "cow";
}
public class MappingResourceZoo : Profile
{
public MappingResourceZoo()
{
CreateMap<Cow, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
CreateMap<Pig, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
CreateMap<MammalHouse, Zoo>()
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Cows.Concat<IMammel>(src.Pigs)));
}
}