.NET 通用多条件动态参数查询方法 - SqlSugar ORM
通用查询用途
一般我们Grid控件,会有很多条件传给后台,如果每个条件都写一个逻辑的话,那么工作量将非常大,所以通用查询功能是每个软件必备的,
SqlSugar将通用查询封装到支持了树型条件,并且支持所有常用的操作,用SqlSugar或者不用SqlSugar的都可参参考一下
1、简单多条件多动参数
创建数据库对象
//创建数据库对象 SqlSugarClient SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = "Server=.xxxxx",//连接符字串 DbType = DbType.SqlServer, //数据库类型 IsAutoCloseConnection = true //不设成true要手动close });
前台传的JSON格式 [{},{},{}]
1 2 3 4 | [ { "FieldName" : "id" , "ConditionalType" : "0" , "FieldValue" : "1" }, { "FieldName" : "name" , "ConditionalType" : "0" , "FieldValue" : "jack" } ] |
后台代码
1 2 3 4 5 6 7 8 9 10 | //手动构造 var conModels = new List<IConditionalModel>(); conModels.Add( new ConditionalModel{ FieldName = "id" ,ConditionalType=ConditionalType.Equal,FieldValue= "1" }); conModels.Add( new ConditionalModel{ FieldName = "name" ,ConditionalType=ConditionalType.Equal,FieldValue= "jack" }); //5.0.5.1 Json直接序列化 var conModels= db.Context.Utilities.JsonToConditionalModels(json) var student = db.Queryable<Student>().Where(conModels).ToList(); //select * from Student where id=1 and name = 'jack' |
这种比较简单 多一条记录就多一个AND
2、二级多条件动态参数
这种模式对于表格查询已经够用了,支持到2级查询,并且AND OR都比较灵活了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [ { "FieldName" : "id" , "FieldValue" : "1" , "ConditionalType" : 10}, { "FieldName" : "id" , "FieldValue" : null , "ConditionalType" : 12}, { "ConditionalList" : [{ "Key" : 1, "Value" : { "FieldName" : "id" , "FieldValue" : "2" , "ConditionalType" : 0 } }, { "Key" : 0, "Value" : { "FieldName" : "id" , "FieldValue" : "2" , "ConditionalType" : 0 } }] }] //5.0.5.1 Json直接序列化 var whereList= db.Context.Utilities.JsonToConditionalModels(json); var list = db.Queryable<Order>().Where(whereList).ToList(); |
生成的Sql:
1 2 3 | WHERE [id] <> @Conditid0 AND [id] IS NOT NULL OR ( [id] = @Conditid10000 AND [id] = @Conditid20000 ) |
说明:ConditionalList 第一个Key为1 那么就会生成 Or( 条件 )
ConditionalList 第一个Key为0 那么就会生成 And( 条件 )
Key表式运算符: And =0, Or=1
例子1:ConditionalList 集合中 有3条记录 key =1 , key =0 ,key=1
生成的Sql OR(条件 AND 条件 OR条件)
例子2:ConditionalList 集合中 有1条记录 key =1
生成的Sql OR(条件)
例子3:ConditionalList 集合中 有4条记录 key =0,key=1,key=1,key=1
生成的Sql AND (条件 OR 条件 OR条件 OR 条件)
这种模式只支持2级操作,需要更多层级就实现不了了
3、树型动态条件 (请升级5.0.5.1)
这种就比较强大了,一般用于表的公开API等操作,可以构造任何层级的条件 ,可以支持树型条件
Key表式运算符: And =0, Or=1, null=-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | [{ "ConditionalList" : [{ "Key" : -1, "Value" : { "FieldName" : "id" , "FieldValue" : "2" , "ConditionalType" : 0 } }, { "Key" : 0, "Value" : { "FieldName" : "name" , "FieldValue" : "2" , "ConditionalType" : 0 } }, { "Key" : 0, "Value" : { "ConditionalList" : [{ "Key" : -1, "Value" : { "FieldName" : "price" , "FieldValue" : "1" , "ConditionalType" : 0 } }, { "Key" : 0, "Value" : { "FieldName" : "CustomId" , "FieldValue" : "1" , "ConditionalType" : 0 } }] } }] }] |
生成的SQL:
1 2 3 4 | WHERE ( [id] = @Conditid10001 AND [name] = @Conditname20001 AND( [price] = @Conditprice10000 AND [CustomId] = @ConditCustomId20000 ) ) |
C#代码
1 2 | var conditionalModels = db.Context.Utilities.JsonToConditionalModels(json); var list = db.Queryable<Order>().Where(conditionalModels).ToList(); |
更多用例:https://www.donet5.com/Ask/9/14378
3、操作符解释
ConditionalTypek是一个枚举
枚举 | 枚举值 | 描述 |
---|---|---|
Equal | 0 | 等于 |
Like | 1 | 模糊查询 |
GreaterThan | 2 | 大于 |
GreaterThanOrEqual | 3 | 大于等于 |
LessThan | 4 | 小于 |
LessThanOrEqual | 5 | 小于等于 |
In | 6 |
In操作 正确格式 X,Y,Z 错误格式 'X','Y','z' |
NotIn | 7 | Not in操作 参数和in一样 |
LikeLeft | 8 | 左模糊 |
LikeRight | 9 | 右模糊 |
NoEqual | 10 | 不等于 |
IsNullOrEmpty | 11 | 是null或者'' |
IsNot | 12 |
情况1 value不等于null 字段<> x 情况2 value等于null 字段 is not null |
NoLike | 13 | 模糊查询取反 |
EqualNull | 14 |
情况1 value不等于null 字段= x 情况2 value等于null 字段 is null
|
InLike | 15 |
正确格式 X,Y,Z 错误格式 'X','Y','z' 生在的Sql : ( id like '%X%' or id like '%Y%' or id like '%Z%') |
4、列名验证或者转换
需求1:实体和表中字段名称不一样的情况下,我们可以做下面转换
1 2 3 4 | foreach ( var r in conModels) { r.FieldName =db.EntityMaintenance.GetDbColumnName<Order>(r.FieldName ); //这样就支持了用实体类中的属性作为参数 } |
看文档:需求2:我要验证前端传过来的属性名和实体一样,列名虽然防注入,但是还是可以任意传,对于高安全级别项目加个验证更保险
https://www.donet5.com/Home/Doc?typeId=1202
5、类型转换
比如PGSQL不支持字符串参数与INT类型相等,我们可以使用类型转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //SqlSugar自带的类型转换 new ConditionalModel() { FieldName = "id" , ConditionalType = ConditionalType.Equal, FieldValue = "1" , FieldValueConvertFunc=it=>SqlSugar.UtilMethods.ChangeType2(it, typeof ( int )) } //自个实现类型转换 new ConditionalModel() { FieldName = "id" , ConditionalType = ConditionalType.Equal, FieldValue = "1" , FieldValueConvertFunc=it=>Convert.ToInt32(it)) } |
6、多表查询去别名
1 2 3 4 5 6 7 8 9 10 11 | List<IConditionalModel> conModels = new List<IConditionalModel>(); conModels.Add( new ConditionalModel{ FieldName = "id" , ConditionalType = ConditionalType.Equal,FieldValue= "1" }); //查询 var list=db.Queryable<Order>() .LeftJoin<Custom> ((o,i) => o.CustomId == cus.Id) .LeftJoin<OrderDetail> ((o,i,c) => o.Id == oritem.OrderId) .Select((o,i,c)=> new ViewOrder{ Id=o.Id CustomName=c.Name }) // 是一个新类 .MergeTable() //通过MergeTable处理下面的查询就不需要加上 (o,i,c) 的别名限制了 .Where(conModels) //因为Select通过Mergetable变成了一个新表,也就是说新表只有 id和CustomName .ToList(); |
7、未来计划
未来会打算支持 Sql函数,真正做到所有的查询条件都能用
安装: Nuget SqlSugarCore
源码: https://github.com/donet5/SqlSugar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构