Сопоставить класс нумерации объектов с классом нумерации страниц - PullRequest
0 голосов
/ 03 января 2019

У меня есть следующий класс PaginatedList.

public class PaginatedList<T> : List<T>
{
    public int PageIndex { get; }
    public int TotalRecords { get; }
    public int TotalPages { get; }

    public PaginatedList(IEnumerable<T> items, int totalRecords, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalRecords = totalRecords;
        TotalPages = (int)Math.Ceiling(TotalRecords / (double)pageSize);

        AddRange(items);
    }

    public bool HasPreviousPage => PageIndex > 1;

    public bool HasNextPage => PageIndex < TotalPages;

    public static async Task<PaginatedList<T>> CreateAsync(
        IQueryable<T> source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
        return new PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}

Я использую этот класс для получения информации о нумерации страниц для списка сущностей, полученного с помощью EF.

Вот как я использую этот класс для возвращения списка пользователей с информацией о нумерации страниц.

var users = await PaginatedList<User>.CreateAsync(userQuery, pageIndex, pageSize);

Над вызовом вернется PaginatedList<User> объект.

Если у меня есть класс DTO для этой сущности, назовем его UserDto. Как использовать automapper для преобразования PaginatedList<User> в PaginatedList<UserDto>, чтобы в результате были все объекты userDto, а также информация о разбиении на страницы?

Иначе, есть ли другой / лучший способ добиться чего-то похожего?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

В итоге я создал еще один фабричный метод в PaginatedList, который будет обрабатывать преобразование.

public static async Task<PaginatedList<TResult>> CreateAsync<TSource>(
    IQueryable<TSource> source, int pageIndex, int pageSize)
{
    Ensure.It.IsGreaterThan(0, pageIndex);
    Ensure.It.IsGreaterThan(0, pageSize);

    var count = await source.CountAsync();
    var items = await source.Skip((pageIndex - 1) * pageSize)
        .Take(pageSize)
        .Select(ufc => Mapper.Map<TResult>(ufc))
        .ToListAsync();
    return new PaginatedList<TResult>(items, count, pageIndex, pageSize);
}

Затем создайте существующий метод CreateAsync для вызова этого нового метода CreateAsync<TSource>.

public static async Task<PaginatedList<TResult>> CreateAsync(
    IQueryable<TResult> source, int pageIndex, int pageSize)
{
    return await CreateAsync<TResult>(source, pageIndex, pageSize);
}

При этом, если мы хотим продолжать возвращать один и тот же класс Entity, мы можем использовать его следующим образом

await PaginatedList<User>.CreateAsync(_dbContext.User.AsQueryable(), pageIndex, pageSize)

И если мы хотим преобразовать класс сущности, чтобы он возвращал класс Dto или другой класс, его можно использовать следующим образом:

await PaginatedList<UserDto>.CreateAsync(_dbContext.User.AsQueryable(), pageIndex, pageSize)

Если мы не конвертируем Entity в другой класс, нам не нужно ничего указывать в конфигурации автоматического преобразователя. Но если вы хотите отобразить сущность в другой класс, ее необходимо настроить в автоматическом преобразователе.

Более или менее, вот как выглядит класс PaginatedList

public class PaginatedList<TResult> : List<TResult>
{
    public int PageIndex { get; }
    public int TotalRecords { get; }
    public int TotalPages { get; }

    public PaginatedList(IEnumerable<TResult> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalRecords = count;
        TotalPages = (int)Math.Ceiling(TotalRecords / (double)pageSize);

        AddRange(items);
    }

    public bool HasPreviousPage => PageIndex > 1;

    public bool HasNextPage => PageIndex < TotalPages;

    public static async Task<PaginatedList<TResult>> CreateAsync<TSource>(
        IQueryable<TSource> source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip((pageIndex - 1) * pageSize)
            .Take(pageSize)
            .Select(ufc => Mapper.Map<TResult>(ufc))
            .ToListAsync();
        return new PaginatedList<TResult>(items, count, pageIndex, pageSize);
    }

    public static async Task<PaginatedList<TResult>> CreateAsync(
        IQueryable<TResult> source, int pageIndex, int pageSize)
    {
        return await CreateAsync<TResult>(source, pageIndex, pageSize);
    }
}
0 голосов
/ 03 января 2019

Automapper идеально подходит для меня, но нам нужно создать конструктор по умолчанию для PaginatedList class

public PaginatedList()
{
    PageIndex = 0;
    TotalRecords = 0;
    TotalPages = 0;
}

-------------------------------- Пример

class User
{
    public string Name { get; set; }
}

class UserDto
{
    public string NameDto { get; set; }
}

public class UserProfile: Profile
{
    public UserProfile()
    {
        CreateMap<User, UserDto>()
            .ForMember(target => target.NameDto, x => x.MapFrom(source => source.Name))
            .ReverseMap();
    }
}

internal class Program
{
   private static void Main(string[] args)
   {
       Mapper.Initialize(config =>
       {
           config.AddProfile<UserProfile>();
       });

       var items = new List<User> { new User { Name = "First name" } };

       var users = new PaginatedList<User>(items, 1, 0, 1);

       var usersDtos = Mapper.Map<PaginatedList<UserDto>>(users);

   }

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...