AutoMapper中是否可以根据类型将集合项复制到特定集合?

时间:2016-01-25 15:10:04

标签: c# automapper

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

是否可以使用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();
    }
}

1 个答案:

答案 0 :(得分:1)

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

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);
    }
}