C#使用SqlSuger如何通过优化代码,提高查询效率


前言

本文使用Asp.Net Core和SqlSuger框架技术实现举例。

当数据量特别大时,如何通过优化代码,进而优化sql,从而提高sql查询效率。
sqlsuger示例代码:

DateTime startTime = new DateTime(2024,10,12,12,00,00);
DateTime endTime = new DateTime(2024,10,13,12,00,00);
//在IOLOg中查询,根据时间、状态、序列号集筛选出对应的数据
var IOLogList = _BaseRepository.Context.Queryable<IOLog>()
    .WhereIF(startTime != null, i => i.StartTime >= startTime)
    .WhereIF(endTime != null, i => i.EndTime <= endTime)
    .Where(i => i.State == 1)
    .Where(i => SqNoList.Contains(i.SqNo))
    .ToList();

生成的sql:

SELECT [Id],[seq_no],[qty],[group_code],[process_code],[station_code],[start_time],[end_time],[p_date],[state] 
FROM [IOLog] WITH(NOLOCK)   
WHERE ( [start_time] >= @StartTime0 )  AND ( [State] = @State1 )  AND  ([seq_no] IN ('SEQ202410140003-001','SEQ202410140003-002','SEQ202410140003-003','SEQ202410140003-004','SEQ202410140003-005','SEQ202410140003-006','SEQ202410140003-007','SEQ202410140003-008','SEQ202410140003-009','SEQ202410140003-010','SEQ202410140003-011'))  
--{"@StartTime0":"2024-10-12T12:00:00.000","@State1":1}

一、显示SqlSuger生成的Sql

将sqlsuger语法生成的sql通过命令窗口打印出来,方便使用数据库查询,检查校验sql。

public class DbOperation
{
	public static void AddDb(IConfiguration Configuration)
	{
		//获取配置文件字符串
	    string connStr = Configuration.GetConnectionString("dbConnection");
	    //0表示MySql,1为SqlServer
	    int dbType = Convert.ToInt32(Configuration.GetConnectionString("dbType"));
	
	    SugarIocServices.AddSqlSugar(new List<IocConfig>() {
	    	//默认数据库
	           new IocConfig() {
	            ConfigId = "0",//默认db
	            ConnectionString = connStr,
	            DbType = (IocDbType)dbType,
	            IsAutoCloseConnection = true
	        },
	        //其他数据库
	           new IocConfig() {
	            ConfigId = "1",
	            ConnectionString = "替换成你的字符串",
	            DbType = IocDbType.MySql,
	            IsAutoCloseConnection = true
	        }
	           //...增加其他数据库
	        });
	    SugarIocServices.ConfigurationSugar(db =>
	    {
	        //db0数据过滤
	        FilterData(0);
	
	        #region db0,默认数据库显示
	        //全局去锁
	        db.GetConnectionScope(0).CurrentConnectionConfig.MoreSettings = new ConnMoreSettings()
	        {
	            IsWithNoLockQuery = true
	        };
	
	        db.GetConnectionScope(0).Aop.OnLogExecuting = (sql, pars) =>
	        {
	            var param = db.GetConnectionScope(0).Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));
	
	            logger.Info($"【sql语句】{sql}--,{param}\n");
	        };
	
	        db.GetConnectionScope(0).Aop.OnError = (e) =>
	        {
	            logger.Error(e, $"执行SQL出错:{e.Message}");
	        };
	        //SQL执行完
	        db.GetConnectionScope(0).Aop.OnLogExecuted = (sql, pars) =>
	        {
	            //执行完了可以输出SQL执行时间 (OnLogExecutedDelegate) 
	        };
	        #endregion
	
	        #region 其他数据库读取显示设置
	        
	        #endregion
	    });
	
	}
}

在Program.cs里挂载AddDb()

//初始化db
var builder = WebApplication.CreateBuilder(args);
DbOperation.AddDb(builder.Configuration);

注意:sql注入

SqlSuger支持的数据库类型:

//SqlSuger支持的数据库类型
public enum IocDbType
{
    MySql = 0,
    SqlServer = 1,
    Sqlite = 2,
    Oracle = 3,
    PostgreSQL = 4,
    Dm = 5,
    Kdbndp = 6,
    Oscar = 7,
    MySqlConnector = 8,
    Access = 9,
    OpenGauss = 10,
    QuestDB = 11,
    HG = 12,
    ClickHouse = 13,
    GBase = 14,
    Odbc = 0xF,
    Custom = 900
}

二、优化SqlSuger

1.根据业务场景,增加查询条件

假设IOLog表中有字段year,格式为yyyy,如果需要查询2024-10-12的数据,可新增条件year = ‘2024’

DateTime startTime = new DateTime(2024,10,12,12,00,00);
DateTime endTime = new DateTime(2024,10,13,12,00,00);
//在IOLOg中查询,根据时间、状态、序列号集筛选出对应的数据
var IOLogList = _BaseRepository.Context.Queryable<IOLog>()
	.Where(i =>i.Year == "2024" && i.State == 1)
    .WhereIF(startTime != null, i => i.StartTime >= startTime)
    .WhereIF(endTime != null, i => i.EndTime <= endTime)
    .Where(i => SqNoList.Contains(i.SqNo))
    .ToList();

2.SqlSuger语法优化

1、通过模板字符串,进行字符串、时间比较,减少sql参数替换,如$“input_time >= ‘{param}’”;
2、在sqlsuger语法中,Contains转为in,这不会影响sql效率。

//在IOLOg中查询,根据时间、状态、序列号集筛选出对应的数据
var IOLogList = _BaseRepository.Context.Queryable<IOLog>()
    .WhereIF(startTime != null, $"start_time >= '{startTime}'")
    .WhereIF(endTime != null, $"end_time <= '{endTime}'")
    .Where($"state = 1")
    .Where(i => SqNoList.Contains(i.SqNo))
    .ToList();

生成的sql:

SELECT [Id],[seq_no],[qty],[group_code],[process_code],[station_code],[start_time],[end_time],[p_date],[state] 
FROM [IOLog] WITH(NOLOCK)   
WHERE start_time >= '2024/10/12 12:00:00'   AND state = 1   AND  ([seq_no] IN ('SEQ202410140003-001','SEQ202410140003-002','SEQ202410140003-003','SEQ202410140003-004','SEQ202410140003-005','SEQ202410140003-006','SEQ202410140003-007','SEQ202410140003-008','SEQ202410140003-009','SEQ202410140003-010','SEQ202410140003-011')) -- ,{}

3.使用纯Sql执行

1、通过sql查询返回DataTable数据结构解析。

var startTime = "2024/10/12 12:00:00"
var sql = "SELECT * FROM IOLog WITH(NOLOCK) WHERE start_time >= '"+ startTime +"'   AND state = 1 AND  seq_no IN ('SEQ202410140003-001','SEQ202410140003-002','SEQ202410140003-003','SEQ202410140003-004','SEQ202410140003-005','SEQ202410140003-006','SEQ202410140003-007','SEQ202410140003-008','SEQ202410140003-009','SEQ202410140003-010','SEQ202410140003-011')";

var SQLResult = _BaseRepository.Context.Ado.GetDataTable(sql);
foreach (DataRow perRow in SQLResult.Rows)
{
    var item = new IOLog
    {
    	Id = perRow["Id"].ToString(),
    	SeqNo = perRow["seq_no"].ToString(),
    	Qty = perRow["qty"].ToString(),
    	GroupCode = perRow["group_code"].ToString(),
    	ProcessCode = perRow["process_code"].ToString(),
    	StationCode = perRow["station_code"].ToString(),
    	StartTime = perRow["start_time"].ToString(),
    	EndTime= perRow["end_time"].ToString(),
        PDate = perRow["p_date"].ToString(),
        State = perRow["state"].ToString(),
    });
}

2、通过sql查询返回dynamic动态数据结构解析。

var startTime = "2024/10/12 12:00:00"
var sql = "SELECT * FROM IOLog WITH(NOLOCK) WHERE start_time >= '"+ startTime +"'   AND state = 1 AND  seq_no IN ('SEQ202410140003-001','SEQ202410140003-002','SEQ202410140003-003','SEQ202410140003-004','SEQ202410140003-005','SEQ202410140003-006','SEQ202410140003-007','SEQ202410140003-008','SEQ202410140003-009','SEQ202410140003-010','SEQ202410140003-011')";

var result = Context.SqlQueryable<dynamic>(sql)
    .ToList();
foreach (var io in result)
{
    var item = new IOLog
    {
    	Id = io.Id.ToString(),
    	SeqNo = io.seq_no.ToString(),
    	Qty = io.qty.ToString(),
    	GroupCode = io.group_code.ToString(),
    	ProcessCode = io.process_code.ToString(),
    	StationCode = io.station_code.ToString(),
    	StartTime = io.start_time.ToString(),
    	EndTime= io.end_time.ToString(),
        PDate = io.p_date.ToString(),
        State = io.state.ToString(),
    });
}

总结

sqlsuger实现sql语句,在where条件里的处理,主要是通过参数替换,当查询数据量过大时,可通过上述 二-2 描述的优化。

### SqlSugar 和 Entity Framework 的区别、优点和缺点 #### 一、基本概念 SqlSugar 是一种轻量级的 ORM 框架,专注于简化数据库操作并提供高效的数据访问能力[^2]。而 Entity Framework (EF) 则是一个功能强大的 ORM 工具,广泛应用于 .NET 平台的企业级应用开发中[^3]。 --- #### 二、主要区别 | 特性 | SqlSugar | Entity Framework | |---------------------|---------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------| | **设计目标** | 面向中小型企业或项目,注重简单性和易用性 | 面向大型企业级应用,强调全面的功能支持 | | **学习曲线** | 学习成本较低,易于上手 | 功能强大但相对复杂,初学者可能需要更多时间熟悉 | | **性能表现** | 性能较高,尤其适用于中小型项目的高频读写场景 | 对于复杂的业务逻辑有良好的支持,但在某些高性能场景下可能会稍逊 | | **扩展性** | 扩展有限,更适合简单的 CRUD 场景 | 支持多种高级特性(如延迟加载、缓存等),具有更高的灵活性 | --- #### 三、各自的优点 ##### SqlSugar 的优点 1. **轻量化**: SqlSugar 设计精简,占用资源少,适合小型到中型的应用程序[^2]。 2. **高效率**: 提供了丰富的 API 接口,能够快速完成常见的增删改查操作。 3. **灵活配置**: 可以通过 Fluent API 或者 XML 文件轻松定义实体类与数据库表的关系。 4. **兼容性强**: 支持 SQL Server、MySQL、PostgreSQL 等主流数据库系统[^2]。 ##### Entity Framework 的优点 1. **强大的 LINQ 查询支持**: EF 允许开发者利用 C# 中熟悉的 LINQ 表达式来进行数据检索[^4]。 2. **自动迁移机制**: Code First 方式允许自动生成数据库结构,并且可以通过 Migration 来实现版本控制。 3. **广泛的生态系统**: 社区活跃,插件众多,文档详尽,遇到问题容易找到解决方案。 4. **事务管理内置**: 自动化处理分布式事务,减少手动编码的工作量。 --- #### 四、各自的缺点 ##### SqlSugar 的缺点 1. **社区规模较小**: 相较于 EF,其生态不够完善,官方更新频率也可能低于预期。 2. **缺乏高级特性**: 不具备像 EF 这样的延迟加载等功能,无法完全满足复杂应用场景下的需求。 3. **调试困难**: 当出现问题时,由于资料较少,排查起来会更加耗时费力。 ##### Entity Framework 的缺点 1. **运行开销较大**: 尤其是在初次加载模型或者频繁切换上下文的情况下,可能导致性能下降[^3]。 2. **陡峭的学习曲线**: 新手入门门槛较高,尤其是面对 DB Context 生命周期管理和依赖注入等问题时[^4]。 3. **不适合极端优化场景**: 如果应用程序对每毫秒都极其敏感,则 EF 可能不是最佳选择,因为它的抽象层引入了一定程度上的额外负载。 --- #### 五、适用范围建议 - 使用 **SqlSugar**: - 开发周期短的小型至中型项目; - 数据库交互较为基础,不需要太多复杂查询的情况; - 希望降低初始设置难度的同时保持较高的执行速度。 - 使用 **Entity Framework**: - 复杂度较高的企业管理信息系统或其他大规模生产环境中的软件构建; - 需要充分利用现代编程范式的便利之处,例如 Lambda 函数和异步方法的支持; - 关注长期维护性和可扩展性的场合。 --- ```csharp // 示例代码展示如何在两种框架下创建新记录 // SqlSugar 实现 var db = new SqlSugarClient(new ConnectionConfig() { ... }); Student student = new Student(); student.Name = "李四"; db.Insertable(student).ExecuteCommand(); // Entity Framework 实现 using (var context = new SchoolContext()) { var student = new Student { Name = "王五" }; context.Students.Add(student); await context.SaveChangesAsync(); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心,你呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值