当前位置: 首页 > news >正文

多表分页联查——EF Core方式和Dapper方式

1.PageResult

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

/// <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.业务逻辑层接口

Task<Result<PageResult<OrderListWithItemsVO>>> GetOrderListAsync(OrderQueryDto orderQueryDto);

2.3.业务逻辑层实现类

public async Task<Result<PageResult<OrderListWithItemsVO>>> GetOrderListAsync(OrderQueryDto orderQueryDto)
{//拿到当前登录用户idvar userId=_userContext.GetUserIdOrThrow();//将用户id作为参数去查询他的订单列表var domain=await _orderRepository.GetOrderListAsync(orderQueryDto.Current,orderQueryDto.Size,orderQueryDto.Status,userId);//映射为vovar 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.数据访问层接口

 Task<PageResult<Order>> GetOrderListAsync(int current, int size, int? status, long userId);

2.5.数据访问层实现类

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,并赋值给 OrderItemsdomainOrder.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

{"ConnectionStrings": {"DefaultConnection": "Server=.;Database=YourDatabase;User Id=sa;Password=YourPassword;TrustServerCertificate=True;"}
}

3.3.数据访问层具体实现,其他不变

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};// 直接映射为领域实体Ordervar 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;
";// 映射为领域实体OrderItemvar 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};
}
}

http://www.dtcms.com/a/562143.html

相关文章:

  • 做网站要找什么公司信息门户网站制作费用
  • wordpress网站后缀网站开发文档网站
  • 营销单页网站模板网站建设 6万贵不贵
  • 体育西网站开发设计深圳市住房和建设局官网
  • 数据结构 10 二叉树作业
  • 网站建设视频教程 百度云如何做网站赚钱6
  • HTML5 测验
  • 沧州网站建设王宝祥wordpress能恢复修改前吗
  • 有没有专门做京东天猫的人才网站e4a能建设网站吗
  • Java记录类:简化数据载体的新选择
  • 郑州做网站开发销售潍坊做网站
  • C++—string(1):string类的学习与使用
  • 做一张网站专栏背景图网页设计模板网站
  • 关于企业网站建设的市场比质比价调查报告手机制作ppt的软件免费
  • 做外贸网站可以收付款吗电商网站建站
  • 响水专业做网站手机wap网站怎么做
  • 催收网站开发要看网的域名是多少
  • 怎么用ps做网站幻灯片做一个app的成本
  • 河南省台前县建设局网站织梦小说网站源码
  • 在线免费视频网站推广安卓小程序开发入门
  • 网站维护电话站长统计代码
  • 数学分析简明教程——2.3 (未完)
  • 计网5.3.3 TCP连接管理
  • 云南哪几个建网站公司甘肃做网站多少钱
  • verilog 中函数和任务的区别,举例说明
  • 网页制作与网站建设实战大全 pdf有名的软件开发公司
  • asyncio.get_running_loop() vs asyncio.get_event_loop() 作用与区别
  • 网站建设公司怎么挖掘客户房产网站建设方案论文
  • 美丽南方的网站建设资讯网站的好处
  • X-anylabelIng运行自动标注报错cannot import name ‘_C‘ from ‘sam2‘解决