将实体分页类映射到dto分页类

时间:2019-01-03 01:34:04

标签: c# automapper

我有以下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。如何使用自动映射器将PaginatedList<User>转换为PaginatedList<UserDto>,以便结果将包含所有userDto对象以及分页信息?

否则,还有另一种/更好的方法来实现类似的目的吗?

2 个答案:

答案 0 :(得分:0)

Automapper非常适合我,但需要在PaginatedList类上创建默认构造函数

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

   }

}

答案 1 :(得分:0)

我最终在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转换为其他类,则无需在automapper配置中指定任何内容。但是,如果要将实体映射到其他类,则需要在自动映射器中对其进行配置。

或多或少,这是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);
    }
}