1.PageResult
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Water.Infrastructure.Common.Utils
{
/// <summary>
/// 封装分页查询结果
/// </summary>
public class PageResult<T>
{
/// <summary>总记录数</summary>
public long Total { get; set; }
/// <summary>当前页数据集合(默认初始化空列表,避免空引用)</summary>
public List<T> Records { get; set; } = new List<T>();
/// <summary>无参构造函数</summary>
public PageResult() { }
/// <summary>带参构造函数(总记录数 + 数据集合)</summary>
public PageResult(long total, List<T> records)
{
Total = total;
Records = records;
}
}
}
2.EF Core方式
2.1.controller
cs
/// <summary>
/// 查询订单列表(含商品明细)
/// </summary>
/// <param name="queryDto"></param>
/// <returns></returns>
[HttpGet("list")]
public async Task<ActionResult<Result<PageResult<List<OrderListWithItemsVO>>>>> GetOrderListAsync([FromQuery] OrderQueryDto orderQueryDto)
{
_logger.LogInformation("查询订单列表(含商品明细),状态id:{id},page:{page},pageSize:{pageSize}", orderQueryDto.Status,orderQueryDto.Current,orderQueryDto.Size);
var result = await _orderService.GetOrderListAsync(orderQueryDto);
return Ok(result);
}
2.2.业务逻辑层接口
cs
Task<Result<PageResult<OrderListWithItemsVO>>> GetOrderListAsync(OrderQueryDto orderQueryDto);
2.3.业务逻辑层实现类
cs
public async Task<Result<PageResult<OrderListWithItemsVO>>> GetOrderListAsync(OrderQueryDto orderQueryDto)
{
//拿到当前登录用户id
var userId=_userContext.GetUserIdOrThrow();
//将用户id作为参数去查询他的订单列表
var domain=await _orderRepository.GetOrderListAsync(orderQueryDto.Current,orderQueryDto.Size,orderQueryDto.Status,userId);
//映射为vo
var voList = domain.Records.Select(order =>
{
var vo = _mapper.Map<OrderListWithItemsVO>(order);
vo.StatusDesc = GetStatusDesc(vo.Status);
vo.Items = _mapper.Map<List<OrderItemVo>>(order.OrderItems);
vo.PayStatusDesc = GetPayStatusDesc(vo.PayStatus);
return vo;
}).ToList();
var resultPage = new PageResult<OrderListWithItemsVO>
{
Total = voList.Count,
Records = voList
};
return Result<PageResult<OrderListWithItemsVO>>.Success(resultPage);
}
/// <summary>
/// 转换订单状态
/// </summary>
/// <param name="status"></param>
/// <returns></returns>
private string GetStatusDesc(int status) => status switch
{
1 => "待付款",
2 => "待接单",
3 => "已接单",
4 => "派送中",
5 => "已完成",
6 => "已取消",
7 => "退款",
_ => "未知状态"
};
/// <summary>
/// 转换订单支付状态
/// </summary>
/// <param name="status"></param>
/// <returns></returns>
private string GetPayStatusDesc(int status) => status switch
{
0 => "未支付",
1 => "已支付",
2 => "退款",
_ => "未知状态"
};
2.4.数据访问层接口
cs
Task<PageResult<Order>> GetOrderListAsync(int current, int size, int? status, long userId);
2.5.数据访问层实现类
cs
public async Task<PageResult<Water.Domain.Entities.Order>> GetOrderListAsync(int current, int size, int? status, long userId)
{
IQueryable<Water.Infrastructure.Data.Entities.Order> query = _dbContext.Orders.Include(i=>i.OrderDetails).ThenInclude(t=>t.WaterSpec).Where(w => w.UserId == userId);
if (status.HasValue)
{
query = query.Where(w => w.Status == status);
}
// 1. 查询总记录数
var total = await query.CountAsync();
// 2. 分页查询数据
var dataOrders = await query
.Skip((current - 1) * size)
.Take(size)
.ToListAsync();
// 3. 批量关联订单项(避免循环查库)
var orderIds = dataOrders.Select(o => o.Id).ToList();
var orderDetails = await _dbContext.OrderDetails
.Include(od => od.WaterSpec)
.Where(od => orderIds.Contains(od.OrderId))
.ToListAsync();
foreach (var order in dataOrders)
{
order.OrderDetails = orderDetails.Where(od => od.OrderId == order.Id).ToList();
}
// 4. 转换为领域实体
var domainOrders = dataOrders.Select(dataOrder =>
{
var domainOrder = _mapper.Map<Water.Domain.Entities.Order>(dataOrder);
// 将数据层 OrderDetail 转换为领域层 OrderItem,并赋值给 OrderItems
domainOrder.OrderItems = _mapper.Map<List<Water.Domain.Entities.OrderItem>>(dataOrder.OrderDetails);
return domainOrder;
}).ToList();
// 5. 封装分页结果
return new PageResult<Water.Domain.Entities.Order>
{
Total = total,
Records = domainOrders
};
}
2.6.AutoMapper映射
数据库OrderDetail → [映射配置] → 领域层OrderItem → 填充到领域Order的OrderItems → [映射配置] → VO层OrderItemVo → 填充到VO的Items
3.Dapper方式
3.1.引包
3.2.appsettings
cs
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=YourDatabase;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"
}
}
3.3.数据访问层具体实现,其他不变
cs
public class OrderRepository : IOrderRepository
{
private readonly WaterDbContext _dbContext;
private readonly IMapper _mapper;
private readonly string _connectionString;
public OrderRepository(WaterDbContext dbContext, IMapper mapper, IConfiguration configuration)
{
_dbContext = dbContext;
_mapper = mapper;
_connectionString = configuration.GetConnectionString("DefaultConnection")
?? throw new ArgumentNullException("连接字符串未配置");
}
public async Task<PageResult<Water.Domain.Entities.Order>> GetOrderListAsync(int current, int size, int? status, long userId)
{
//Dapper方式
// 直接创建数据库连接(使用完自动释放)
using IDbConnection connection = new SqlConnection(_connectionString);
connection.Open(); // 手动打开连接(Dapper会自动处理,但显式打开更直观)
// 1. 查询订单主表(分页+条件)
var orderSql = @"
SELECT Id, Number, Status, OrderTime, CheckoutTime, Amount, Consignee, Phone,
UserId, AddressBookId, PayStatus, Remark, Address, UserName,
EstimatedDeliveryTime, DeliveryAmount
FROM [Order]
WHERE UserId = @UserId
AND (@Status IS NULL OR Status = @Status)
ORDER BY OrderTime DESC
OFFSET (@Current - 1) * @Size ROWS FETCH NEXT @Size ROWS ONLY;
";
var orderParams = new
{
UserId = userId,
Status = status,
Current = current,
Size = size
};
// 直接映射为领域实体Order
var orders = (await connection.QueryAsync<Water.Domain.Entities.Order>(orderSql, orderParams)).ToList();
// 2. 查询总记录数
var countSql = @"
SELECT COUNT(1) FROM [Order]
WHERE UserId = @UserId
AND (@Status IS NULL OR Status = @Status);
";
int total = await connection.ExecuteScalarAsync<int>(countSql, orderParams);
if (!orders.Any())
{
return new PageResult<Water.Domain.Entities.Order>
{
Total = total,
Records = new List<Water.Domain.Entities.Order>()
};
}
// 3. 查询订单明细(关联WaterSpec,映射为OrderItem领域实体)
var orderIds = orders.Select(o => o.Id).ToList();
var orderDetailSql = @"
SELECT
od.Id,
od.Name,
od.Image,
ws.SpecName,
ws.Capacity,
od.Number,
ws.Price AS SpecPrice,
od.Amount,
od.OrderId,
od.WaterInfoId,
od.WaterSpecId
FROM OrderDetail od
JOIN WaterSpec ws ON od.WaterSpecId = ws.Id
WHERE od.OrderId IN @OrderIds;
";
// 映射为领域实体OrderItem
var orderItems = (await connection
.QueryAsync<OrderItem>(orderDetailSql, new { OrderIds = orderIds }))
.ToList();
// 4. 关联订单与明细(填充Order的OrderItems属性)
foreach (var order in orders)
{
order.OrderItems = orderItems
.Where(od => od.OrderId == order.Id)
.ToList();
}
// 5. 返回领域实体的分页结果
return new PageResult<Water.Domain.Entities.Order>
{
Total = total,
Records = orders
};
}
}