是否可以在自动映射器中根据其类型将集合项复制到特定集合

本文关键字:集合 类型 复制 映射 是否 | 更新日期: 2023-09-27 18:31:44

>我有一个场景,我有一个域模型,它有一个基于接口的集合,这意味着可能有两种可能的类型之一。然后,我想将其映射到一个视图模型,该模型相似但包含两个集合,每种类型一个集合。

是否可以使用 AutoMapper 执行此操作,以便根据相关项目的类型将单个集合映射到两个集合?

我在下面包含了一些示例对象,并带有一些注释掉的行,其中一个显示了我使用 SourceType 尝试的内容,但我找不到一种方法来工作。

域对象

public interface IItemType
{
}
public class ItemTypeOne : IItemType
{
}
public class ItemTypeTwo : IItemType
{
}
public class DomainModel
{
    public List<IItemType> Items;
}

查看模型

public class ViewModel
{
    public List<ViewModelItemOne> ItemTypeOnes = new List<ViewModelItemOne>();
    public List<ViewModelItemTwo> ItemsTypeTwos = new List<ViewModelItemTwo>();
}
public class ViewModelItemOne
{
    public List<ItemTypeOne> ItemTypeOnes;
    public List<ItemTypeTwo> ItemsTypeTwos;
}
public class ViewModelItemTwo
{
    public List<ItemTypeOne> ItemTypeOnes;
    public List<ItemTypeTwo> ItemsTypeTwos;
}

映射

class Program
{
    static void Main(string[] args)
    {
        var dm = new DomainModel()
        {
            Items = new List<IItemType>()
            {
                new ItemTypeOne(),
                new ItemTypeOne(),
                new ItemTypeOne(),
                //new ItemTypeTwo()
            }
        };
        Mapper.CreateMap<DomainModel, ViewModel>();
        Mapper.CreateMap<ItemTypeOne, ViewModelItemOne>();
        Mapper.CreateMap<ItemTypeTwo, ViewModelItemTwo>();
        Mapper.CreateMap<DomainModel, ViewModel>().ForMember(dest => dest.ItemTypeOnes, opt => { opt.MapFrom(src => src.Items); });
        //Mapper.CreateMap<DomainModel, ViewModel>().ForMember(dest => dest.ItemTypeOnes, opt => { opt.Condition(con => con.SourceType == typeof(ItemTypeOne)); opt.MapFrom(src => src.Items); });
        var vm = Mapper.Map<ViewModel>(dm);
        Console.WriteLine(vm.ItemTypeOnes.Count);
        Console.WriteLine(vm.ItemsTypeTwos.Count);
        Console.ReadKey();
    }
}

是否可以在自动映射器中根据其类型将集合项复制到特定集合

您可以通过声明如何设置每个属性来执行此操作:

Mapper.CreateMap<DomainModel, ViewModel>()
      .ForMember(dest => dest.ItemTypeOnes, 
                 opt => opt.MapFrom(src => src.Items.Where(i => i is ItemTypeOne))) 
      .ForMember(dest => dest.ItemsTypeTwos,
                 opt => opt.MapFrom(src => src.Items.Where(i => i is ItemTypeTwo)));

那么这个测试将通过:

[TestClass]
public class TC
{
    [TestMethod]
    public void T()
    {
        var dm = new DomainModel
        {
            Items = new List<IItemType>
        {
            new ItemTypeOne(),
            new ItemTypeOne(),
            new ItemTypeOne(),
            new ItemTypeTwo()
        }
        };
        Mapper.CreateMap<DomainModel, ViewModel>();
        Mapper.CreateMap<ItemTypeOne, ViewModelItemOne>();
        Mapper.CreateMap<ItemTypeTwo, ViewModelItemTwo>();
        Mapper.CreateMap<DomainModel, ViewModel>()
            .ForMember(dest => dest.ItemTypeOnes, opt => opt.MapFrom(src => src.Items.Where(i => i is ItemTypeOne))) 
            .ForMember(dest => dest.ItemsTypeTwos, opt => opt.MapFrom(src => src.Items.Where(i => i is ItemTypeTwo))); ;
        var vm = Mapper.Map<DomainModel, ViewModel>(dm);
        Assert.AreEqual(3, vm.ItemTypeOnes.Count);
        Assert.AreEqual(1, vm.ItemsTypeTwos.Count);
    }
}