21

I'd like to map a paged list of business objects to a paged list of view model objects using something like this:

var listViewModel = _mappingEngine.Map<IPagedList<RequestForQuote>, IPagedList<RequestForQuoteViewModel>>(requestForQuotes);

The paged list implementation is similar to Rob Conery's implementation here: http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/

How can you setup Automapper to do this?

4

7 に答える 7

36

jrummell の回答を使用して、Troy Goode の PagedListで動作する拡張メソッドを作成しました。これにより、どこにでも多くのコードを配置する必要がなくなります...

    public static IPagedList<TDestination> ToMappedPagedList<TSource, TDestination>(this IPagedList<TSource> list)
    {
        IEnumerable<TDestination> sourceList = Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>(list);
        IPagedList<TDestination> pagedResult = new StaticPagedList<TDestination>(sourceList, list.GetMetaData());
        return pagedResult;

    }

使用法は次のとおりです。

var pagedDepartments = database.Departments.OrderBy(orderBy).ToPagedList(pageNumber, pageSize).ToMappedPagedList<Department, DepartmentViewModel>();
于 2012-09-17T16:18:54.317 に答える
13

AutoMapperは、の実装について知らないため、これをそのままではサポートしていませんIPagedList<>。ただし、いくつかのオプションがあります。

  1. IObjectMapper既存のArray/EnumerableMappersをガイドとして使用して、カスタムを作成します。これは私が個人的に行く方法です。

  2. 以下を使用して、カスタムTypeConverterを記述します。

    Mapper
        .CreateMap<IPagedList<Foo>, IPagedList<Bar>>()
        .ConvertUsing<MyCustomTypeConverter>();
    

    Mapper.Mapリストの各要素をマップするために内部で使用します。

于 2010-01-17T19:50:30.443 に答える
8

Troy Goode の PageListを使用している場合は、StaticPagedListマッピングに役立つクラスがあります。

// get your original paged list
IPagedList<Foo> pagedFoos = _repository.GetFoos(pageNumber, pageSize);
// map to IEnumerable
IEnumerable<Bar> bars = Mapper.Map<IEnumerable<Bar>>(pagedFoos);
// create an instance of StaticPagedList with the mapped IEnumerable and original IPagedList metadata
IPagedList<Bar> pagedBars = new StaticPagedList<Bar>(bars, pagedFoos.GetMetaData());
于 2012-03-09T15:03:31.677 に答える
1

PagedList<DomainModel>にマップするAutoMapper の小さなラッパーを作成しましたPagedList<ViewModel>

public class MappingService : IMappingService
{
    public static Func<object, Type, Type, object> AutoMap = (a, b, c) =>
    {
        throw new InvalidOperationException(
            "The Mapping function must be set on the MappingService class");
    };

    public PagedList<TDestinationElement> MapToViewModelPagedList<TSourceElement, TDestinationElement>(PagedList<TSourceElement> model)
    {
        var mappedList = MapPagedListElements<TSourceElement, TDestinationElement>(model);
        var index = model.PagerInfo.PageIndex;
        var pageSize = model.PagerInfo.PageSize;
        var totalCount = model.PagerInfo.TotalCount;

        return new PagedList<TDestinationElement>(mappedList, index, pageSize, totalCount);
    }

    public object Map<TSource, TDestination>(TSource model)
    {
        return AutoMap(model, typeof(TSource), typeof(TDestination));
    }

    public object Map(object source, Type sourceType, Type destinationType)
    {
        if (source is IPagedList)
        {
            throw new NotSupportedException(
                "Parameter source of type IPagedList is not supported. Please use MapToViewModelPagedList instead");
        }

        if (source is IEnumerable)
        {
            IEnumerable<object> input = ((IEnumerable)source).OfType<object>();
            Array a = Array.CreateInstance(destinationType.GetElementType(), input.Count());

            int index = 0;
            foreach (object data in input)
            {
                a.SetValue(AutoMap(data, data.GetType(), destinationType.GetElementType()), index);
                index++;
            }
            return a;
        }

        return AutoMap(source, sourceType, destinationType);
    }

    private static IEnumerable<TDestinationElement> MapPagedListElements<TSourceElement, TDestinationElement>(IEnumerable<TSourceElement> model)
    {
        return model.Select(element => AutoMap(element, typeof(TSourceElement), typeof(TDestinationElement))).OfType<TDestinationElement>();
    }
}

使用法:

PagedList<Article> pagedlist = repository.GetPagedList(page, pageSize);
mappingService.MapToViewModelPagedList<Article, ArticleViewModel>(pagedList);

要素タイプを使用する必要があることが重要です!

ご質問やご提案がありましたら、お気軽にコメントしてください:)

于 2010-11-01T21:45:57.320 に答える
1

AutoMapper は、いくつかのタイプのリストと配列の間の変換を自動的に処理します: http://automapper.codeplex.com/wikipage?title=Lists%20and%20Arrays

IList から継承されたカスタム タイプのリストを自動的に変換するようには見えませんが、次のように回避できます。

    var pagedListOfRequestForQuote = new PagedList<RequestForQuoteViewModel>(
        AutoMapper.Mapper.Map<List<RequestForQuote>, List<RequestForQuoteViewModel>>(((List<RequestForQuote>)requestForQuotes),
        page ?? 1,
        pageSize
于 2010-01-15T17:52:45.413 に答える