我有以下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对象以及分页信息?
否则,还有另一种/更好的方法来实现类似的目的吗?
答案 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);
}
}