通用查詢用途
一般我們Grid控件,會有很多條件傳給背景,如果每個條件都寫一個邏輯的話,那麼工作量将非常大,是以通用查詢功能是每個軟體必備的,
SqlSugar将通用查詢封裝到支援了樹型條件,并且支援所有常用的操作,用SqlSugar或者不用SqlSugar的都可參參考一下
1、簡單多條件多動參數
建立資料庫對象
//建立資料庫對象 SqlSugarClient
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Server=.xxxxx",//連接配接符字串
DbType = DbType.SqlServer, //資料庫類型
IsAutoCloseConnection = true //不設成true要手動close
});
前台傳的JSON格式 [{},{},{}]
[
{"FieldName":"id","ConditionalType":"0","FieldValue":"1"},
{"FieldName":"name","ConditionalType":"0","FieldValue":"jack"}
]
背景代碼
//手動構造
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都比較靈活了
[ {"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:
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
[{
"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:
WHERE ( [id] = @Conditid10001
AND [name] = @Conditname20001
AND( [price] = @Conditprice10000 AND [CustomId] = @ConditCustomId20000 ) )
C#代碼
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 | 等于 | |
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 | 字段= x 字段 is null |
InLike | 15 | 生在的Sql : ( id like '%X%' or id like '%Y%' or id like '%Z%') |
4、列名驗證或者轉換
需求1:實體和表中字段名稱不一樣的情況下,我們可以做下面轉換
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類型相等,我們可以使用類型轉換
//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、多表查詢去别名
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