1. 多表查询实战从基础到复杂场景SqlSugar的多表查询功能在实际项目中非常实用特别是处理复杂业务关系时。我遇到过不少开发者在使用多表查询时踩坑主要是因为对JoinType和查询结果处理不够熟悉。让我们通过一个电商系统的典型场景来深入理解。假设我们有三张表用户表(User)、订单表(Order)和商品表(Product)。典型的查询需求是查询某个用户的所有订单及对应商品信息。用SqlSugar实现这个需求可以这样写var query db.QueryableUser, Order, Product( (u, o, p) new object[] { JoinType.Left, u.Id o.UserId, JoinType.Left, o.ProductId p.Id }) .Where((u, o, p) u.Id userId) .Select((u, o, p) new { UserName u.Name, OrderNo o.OrderNumber, ProductName p.Name, OrderDate o.CreateTime });这里有几个关键点需要注意JoinType指定了连接方式Left确保即使用户没有订单也会出现在结果中多表查询一定要用Select明确指定返回字段避免字段冲突条件过滤要放在Where中而不是Join条件里对于更复杂的场景比如需要动态决定是否关联某张表可以使用条件查询var query db.QueryableUser(); if(includeOrders) { query query.LeftJoinOrder((u,o) u.Id o.UserId); if(includeProducts) { query query.LeftJoinProduct((u,o,p) o.ProductId p.Id); } }2. 动态条件构建的三种实战方案在实际项目中我经常遇到需要根据用户输入动态构建查询条件的场景。SqlSugar提供了非常灵活的解决方案下面分享我在项目中总结出的三种实用模式。方案一WhereIF链式调用这是最简单直观的方式适合条件数量固定但可能不生效的场景var query db.QueryableProduct() .WhereIF(!string.IsNullOrEmpty(keyword), p p.Name.Contains(keyword)) .WhereIF(categoryId 0, p p.CategoryId categoryId) .WhereIF(minPrice 0, p p.Price minPrice) .WhereIF(maxPrice 0, p p.Price maxPrice);方案二ConditionalModel动态构建当条件完全动态时这种方案更合适。比如构建一个高级搜索功能var conditions new ListIConditionalModel(); if(!string.IsNullOrEmpty(keyword)) { conditions.Add(new ConditionalModel { FieldName Name, FieldValue keyword, ConditionalType ConditionalType.Like }); } if(stockAlert) { conditions.Add(new ConditionalModel { FieldName Stock, FieldValue 10, ConditionalType ConditionalType.LessThan }); } var results db.QueryableProduct().Where(conditions).ToList();方案三表达式树动态构建对于需要复杂逻辑的场景可以使用表达式树ExpressionFuncProduct, bool expr p true; if(!string.IsNullOrEmpty(keyword)) { expr expr.And(p p.Name.Contains(keyword)); } if(categoryId 0) { expr expr.And(p p.CategoryId categoryId); } var results db.QueryableProduct().Where(expr).ToList();提示表达式树方案性能最好但复杂度较高建议封装成公共方法复用3. 批量操作性能优化秘籍在处理大批量数据时我踩过不少性能坑。SqlSugar的批量操作功能很强大但用不好反而会成为性能瓶颈。下面分享几个实战优化技巧。批量插入优化普通插入10万条数据可能需要几分钟而用SqlSugar的批量插入只需几秒// 错误做法循环单条插入 foreach(var item in bigList) { db.Insertable(item).ExecuteCommand(); } // 正确做法批量插入 db.Insertable(bigList).ExecuteCommand();批量更新技巧批量更新时要注意分批处理我建议每批不超过1000条var list GetUpdateList(); // 获取待更新数据 for(int i0; ilist.Count; i1000) { var batch list.Skip(i).Take(1000).ToList(); db.Updateable(batch).ExecuteCommand(); }批量删除最佳实践根据我的测试使用In语句删除性能最好var ids GetDeleteIds(); // 获取要删除的ID集合 db.DeleteableProduct().Where(p ids.Contains(p.Id)).ExecuteCommand();对于超大批量(10万)删除建议使用原生SQLdb.Ado.ExecuteCommand(DELETE FROM Product WHERE CreateTime time, new { time DateTime.Now.AddYears(-1) });4. 高阶查询函数实战应用SqlSugar内置的SqlFunc类提供了丰富的SQL函数映射合理使用可以大幅减少数据库计算压力。下面通过几个典型案例说明用法。案例一统计报表查询计算每个分类的商品数量、平均价格等var report db.QueryableProduct() .GroupBy(p p.CategoryId) .Select(p new { CategoryId p.CategoryId, Count SqlFunc.AggregateCount(p.Id), AvgPrice SqlFunc.AggregateAvg(p.Price), MaxPrice SqlFunc.AggregateMax(p.Price), TotalStock SqlFunc.AggregateSum(p.Stock) }).ToList();案例二智能搜索建议实现拼音首字母搜索功能var keyword 手机; // 可以是中文或拼音首字母 var results db.QueryableProduct() .Where(p SqlFunc.Contains( SqlFunc.MergeString(p.Name, p.PinyinCode), keyword)) .ToList();案例三复杂条件判断实现多条件折扣计算逻辑var products db.QueryableProduct() .Select(p new { p.Id, p.Name, p.Price, DiscountPrice SqlFunc.IIF( p.Stock 100 p.Price 1000, p.Price * 0.8m, SqlFunc.IIF( p.CreateTime DateTime.Now.AddMonths(-6), p.Price * 0.9m, p.Price ) ) }).ToList();5. 事务与原生SQL的进阶用法分布式事务处理在微服务架构下我经常需要协调多个数据库操作。SqlSugar的事务处理非常灵活try { db.BeginTran(); // 操作主库 var orderId db.Insertable(order).ExecuteReturnIdentity(); // 操作日志库 var logDb db.GetConnection(logConnection); logDb.Insertable(new Log { Action CreateOrder, OrderId orderId }).ExecuteCommand(); db.CommitTran(); } catch { db.RollbackTran(); throw; }高性能原生SQL对于特别复杂的查询原生SQL往往是更好的选择。这是我的常用模式var sql SELECT p.*, c.Name as CategoryName FROM Product p LEFT JOIN Category c ON p.CategoryId c.Id WHERE p.Stock minStock AND p.Status status; var parameters new { minStock 10, status 1 }; var results db.Ado.SqlQueryProductDto(sql, parameters);存储过程调用处理复杂业务逻辑时存储过程仍然有优势var parameters new SugarParameter[] { new SugarParameter(userId, userId), new SugarParameter(startDate, startDate), new SugarParameter(endDate, endDate) }; var ds db.Ado.UseStoredProcedure().GetDataSetAll(sp_GetUserReport, parameters);6. 性能监控与调优实战查询性能分析启用AOP监控是分析性能问题的好方法db.Aop.OnLogExecuting (sql, pars) { Console.WriteLine($执行SQL{sql}); Console.WriteLine($参数{string.Join(,, pars.Select(p ${p.ParameterName}{p.Value}))}); Console.WriteLine($执行时间{DateTime.Now}); };索引优化建议通过查询分析发现缺失索引var slowQuery db.QueryableOrder() .Where(o o.CreateTime startDate o.CreateTime endDate) .Where(o o.Status 1) .ToList(); // 对应的索引建议 // CREATE INDEX IX_Order_Status_CreateTime ON Order(Status, CreateTime)缓存策略实现对于热点数据实现二级缓存public ListProduct GetHotProducts() { var cacheKey HotProducts; if(db.Ado.GetCache(cacheKey) is ListProduct products) { return products; } products db.QueryableProduct() .Where(p p.IsHot) .Take(20) .ToList(); db.Ado.SetCache(cacheKey, products, 60 * 5); // 缓存5分钟 return products; }7. 复杂查询构建器模式对于超复杂的查询条件我总结出一个构建器模式可以优雅地处理各种组合条件public class ProductQueryBuilder { private ISugarQueryableProduct _query; public ProductQueryBuilder(ISugarQueryableProduct query) { _query query; } public ProductQueryBuilder WithKeyword(string keyword) { if(!string.IsNullOrEmpty(keyword)) { _query _query.Where(p p.Name.Contains(keyword)); } return this; } public ProductQueryBuilder WithCategory(int? categoryId) { if(categoryId.HasValue) { _query _query.Where(p p.CategoryId categoryId.Value); } return this; } public ProductQueryBuilder WithPriceRange(decimal? min, decimal? max) { if(min.HasValue) { _query _query.Where(p p.Price min.Value); } if(max.HasValue) { _query _query.Where(p p.Price max.Value); } return this; } public ISugarQueryableProduct Build() { return _query; } } // 使用示例 var results new ProductQueryBuilder(db.QueryableProduct()) .WithKeyword(手机) .WithCategory(1) .WithPriceRange(1000, 5000) .Build() .ToList();