自动映射自定义集合

时间:2011-11-22 15:05:15

标签: automapper

您好。我有一个类似这样的列表:

public class PagedList<T> : List<T>
{
    public PagedList(IEnumerable<T> collection) : base(collection)
    { }
    public int TotalItems { get; set; }
    public int CurrentPage { get; set; }
    public int PageSize { get; set; }
    //some other properties
}

并在存储库中用于分页

 public PagedList<TEntity> GetPaged(int page)
 {
   var pagedEntities = some_query;
   return pagedEntities.AsPagedList(totalResults, page, pageSize);
 }

同样的PagedList也用于asp mvc视图模型中进行分页。 是否可以使用Automapper将此集合映射到所有属性TotalItems / CurrentPage / ...?

   PagedList<DbItem> dbItems = _repository.GetPages(page);
   var viewItems = new PagedList<SomeItemView>();
   Mapper.Map(dbItems , viewItems);

Tahnk你!

3 个答案:

答案 0 :(得分:5)

这对我有用。你在寻找更通用的东西吗?

public class DbItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ViewItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PagedList<T>: List<T>
{
    public int TotalItems { get; set; }
    public int CurrentPage { get; set; }
    public int PageSize { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        MapItems();
    }

    public static void MapItems()
    {
        Mapper.CreateMap<DbItem, ViewItem>();
        Mapper.CreateMap<PagedList<DbItem>, PagedList<ViewItem>>()
            .AfterMap((s, d) => Mapper.Map<List<DbItem>, List<ViewItem>>(s, d));

        var dbList = new PagedList<DbItem>
                         {
                             new DbItem {Id = 1, Name = "a"}, 
                             new DbItem {Id = 2, Name = "b"}
                         };
        dbList.TotalItems = 2;
        dbList.CurrentPage = 1;
        dbList.PageSize = 10;
        var viewList = Mapper.Map<PagedList<DbItem>, PagedList<ViewItem>>(dbList);

        Console.WriteLine(viewList.TotalItems);
        Console.WriteLine(viewList.CurrentPage);
        Console.WriteLine(viewList.PageSize);
        Console.WriteLine(viewList[0].Id + " " + viewList[0].Name);
        Console.WriteLine(viewList[1].Id + " " + viewList[1].Name);
        Console.ReadLine();
    }
}

答案 1 :(得分:2)

您需要的是自定义类型转换器

    public class PagedListConverter<TIn, TOut> : ITypeConverter<IPagedList<TIn>, IPagedList<TOut>>
    {
        public IPagedList<TOut> Convert(AutoMapper.ResolutionContext context)
        {

            var source = (IPagedList<TIn>)context.SourceValue;

            var mapped = Mapper.Map<IList<TOut>>(source);

            return new StaticPagedList<TOut>(mapped, source.GetMetaData());
        }
    }

用法:

    Mapper.CreateMap<IPagedList<Company>, IPagedList<CompanyViewModel>>().ConvertUsing<PagedListConverter<Company, CompanyViewModel>>();

答案 2 :(得分:0)

对于最近遇到类似问题的人,作为 NoPyGod's answer 的更新,您可以使用 ITypeConverter 实现一般映射。根据{{​​3}}:

<块引用>

AutoMapper 还支持具有任意数量的泛型参数的开放泛型类型转换器:

var configuration = new MapperConfiguration(cfg =>
  cfg.CreateMap(typeof(Source<>), typeof(Destination<>)).ConvertUsing(typeof(Converter<,>)));

来自 Source 的封闭类型将是第一个泛型参数,而 Destination 的封闭类型将是关闭 Converter<,> 的第二个参数。

因此自定义类型转换器将是:

private class Converter<TSource, TDestination>
    : ITypeConverter<PagedList<TSource>, PagedList<TDestination>>
{
    public PagedList<TDestination> Convert(
        PagedList<TSource> source,
        PagedList<TDestination> destination,
        ResolutionContext context) =>
        new PagedList<TDestination>(
            context.Mapper.Map<List<TSource>, List<TDestination>>(source));
        /* Additional settings comes here. */
}

然后注册:

this.CreateMap(typeof(PagedList<>), typeof(PagedList<>)).ConvertUsing(typeof(Converter<,>));