藍燈軟件數據股份有限公司項目,代碼開源。html
SqlSugar是一款輕量級的MSSQL ORM ,除了具備媲美ADO的性能外還具備和EF類似簡單易用的語法。sql
學習列表數據庫
0、功能更新cookie
一、SqlSugar基礎應用session
三、使用SqlSugar實現Join 待更新函數
四、使用SqlSugar實現分頁+分組+多列排序 待更新post
五、節點故障如何進行主從調換性能
1、介簡
優勢:學習
一、優越的性能,查詢使用 reflection.emit 建立IL語言+委託綁定 而後對該對象進行 cache ,datareader直接賦值給cache對象,高性能拉姆達解析,整體性能媲美 ADO.NET ,查詢速度稍慢於datareader但稍快於datatable
二、大量語法糖,拉姆達表達示篩選,新穎的多表查詢 ,方便的分頁等
三、支持NOLOCK查詢,提升性能
四、支持事務
五、內置實體類生成函數,無需使用第三方代碼生成器
六、簡單好用、例子齊全有問必答。
缺點:
目前只支持MSSQL,之後會全面發展
組成:
sqlSugar是由sqlSugarClientr提供統一調用模式 ,sqlSugarClientr是由5個部分組成
一、自身函數
二、實體生成
三、單表查詢
四、多表查詢
五、基類函數
如圖:
2、使用教程
查詢
一、單表或者單視圖查詢:
經過調用 db.Queryable() 的相關擴展函數 輕鬆搞定單表查詢
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
37
|
using
(SqlSugarClient db =
new
SqlSugarClient(connStr))
//開啓數據庫鏈接
{
//查詢全部
var
student = db.Queryable<Student>().ToList();
//查詢單條
var
single = db.Queryable<Student>().Single(c => c.id == 1);
//取10-20條
var
page1 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(
"id"
).Skip(10).Take(20).ToList();
//上一句的簡化寫法,一樣取10-20條
var
page2 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(
"id"
).ToPageList(2, 10);
//查詢條數
var
count = db.Queryable<Student>().Where(c => c.id > 10).Count();
//從第2條開始之後取全部
var
skip = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(
"id"
).Skip(2).ToList();
//取前2條
var
take = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(
"id"
).Take(2).ToList();
// Not like
var
notLike = db.Queryable<Student>().Where(c => !c.name.Contains(
"a"
.ToString())).ToList();
// 能夠在拉姆達使用 ToString和 Convert,比EF出色的地方
var
convert1 = db.Queryable<Student>().Where(c => c.name ==
"a"
.ToString()).ToList();
var
convert2 = db.Queryable<Student>().Where(c => c.id == Convert.ToInt32(
"1"
)).ToList();
//
var
convert3 = db.Queryable<Student>().Where(c => DateTime.Now > Convert.ToDateTime(
"2015-1-1"
)).ToList();
var
convert4 = db.Queryable<Student>().Where(c => DateTime.Now > DateTime.Now).ToList();
//支持字符串Where 讓你解決,更復雜的查詢
var
student12 = db.Queryable<Student>().Where(c => 1 == 1).Where(
"id>@id"
,
new
{id=1}).ToList();
}
|
1
2
3
|
//存在記錄反回true,則否返回false
bool
isAny100 = db.Queryable<Student>().Any(c => c.id == 100);
bool
isAny1 = db.Queryable<Student>().Any(c => c.id == 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
|
/// <summary>
/// 根據條件查詢而且分頁
/// </summary>
/// <param name="name"></param>
/// <param name="sex"></param>
/// <returns></returns>
public
static
List<Student> GetStudent(
string
name,
string
sex,
int
pageIndex,
int
pageSize,
string
orderFileds,
out
int
pageCount)
{
using
(SqlSugarClient db = SugarDao.GetInstance())
{
var
qable = db.Queryable<Student>();
if
(!
string
.IsNullOrEmpty(name))
{
qable = qable.Where(it => it.name.Contains(name));
}
if
(!
string
.IsNullOrEmpty(sex))
{
qable = qable.Where(it => it.sex == sex);
}
if
(!
string
.IsNullOrEmpty(orderFileds))
//無需擔憂注入
{
qable = qable.OrderBy(orderFileds);
}
pageCount = qable.Count();
return
qable.ToPageList(pageIndex, pageSize);
}
}
|
新容器轉換
1
2
3
4
5
6
7
|
public
List<classNew> GetSelectList(
int
id)
{
using
(SugarDao db =
new
SugarDao())
{
return
db.Queryable<Student>().Where(c=>c.id<10).Select(c =>
new
classNew { newid = c.id, newname = c.name,xx_name=c.name }).ToList();
//不支持匿名類轉換,也不建議使用
}
}
|
分組查詢
1
2
3
4
5
6
7
|
public
List<SexTotal> GetSexTotal()
{
using
(SugarDao db =
new
SugarDao())
{
return
db.Queryable<Student>().Where(c => c.id < 20).GroupBy(
"sex"
).Select<Student, SexTotal>(
"Sex,Count=count(*)"
).ToList();
}
}
|
1
|
SELECT
Sex,
Count
=
count
(*)
FROM
Student
WHERE
1=1
AND
(id < 20)
GROUP
BY
Sex
--生成結果
|
三、多表查詢:
說到多表查詢在衆多ORM中不管是性能仍是功能上都不滿意,或者說還不如用SQL,下面是個人創意,放棄了強類型寫法,讓代碼更接近SQL語句編寫,讓SQL徹底可控,也解決了OMR多表的性能問題。
還有ORDERBY、GROUPBY和APPLY等,例子中就不介紹了。
拿EF來比較一下:
EF查詢:
1
2
3
4
5
6
7
8
9
10
11
|
var
reval = (
from
s
in
db.Student
join
sc
in
db.School
on
s.sch_id
equals
sc.id
join
sb
in
db.Subject
on
s.id
equals
sb.sid
into
ssb
from
sb2
in
ssb.DefaultIfEmpty()
select
new
{
s.id,
s.name,
s.sch_id,
s.sex
}).Where(c=>c.id>1).Where(c=>c.id>2).OrderBy(c=>c.id).ThenByDescending(c=>c.name).Skip(10).Take(10).ToList();
|
SqlSugar查詢:
1
2
3
4
|
db.Sqlable().Form<Student>(
"s"
)
.Join<School> (
"sc"
,
"sc.id"
,
"s.sch_id"
, JoinType.INNER)
.Join<subject>(
"sb"
,
"sb.sid"
,
"s.id"
, JoinType.LEFT).Where(
"s.id>@id1"
).Where(
"s.id>@id2"
)
.SelectToPageList<Models.Student>(
"s.*"
,
"s.id asc,s.name desc"
, 2, 10,
new
{ id1=1,id2=2 });
|
更多的SqlSugar查詢:
1
2
3
4
5
6
7
8
9
10
11
|
//表名是字符串寫法
List<School> dataList = db.Sqlable()
.Form(
"school"
,
"s"
)
.Join(
"student"
,
"st"
,
"st.id"
,
"s.id"
, JoinType.INNER)
.Join(
"student"
,
"st2"
,
"st2.id"
,
"st.id"
, JoinType.LEFT).Where(
"s.id>100 and s.id<@id"
).SelectToList<School>(
"st.*"
,
new
{ id = 1 });
//多表分頁
List<School> dataPageList = db.Sqlable()
.Form<school>(
"s"
)
.Join<student>(
"st"
,
"st.id"
,
"s.id"
, JoinType.INNER)
.Join<student>(
"st2"
,
"st2.id"
,
"st.id"
, JoinType.LEFT).Where(
"s.id>100 and s.id<100"
).SelectToPageList<School>(
"st.*"
,
"s.id"
, 1, 10);
|
子查詢加動態拼接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
List<Student> GetStudent(
int
id,
string
name)
{
int
pageCount = 0;
using
(
var
db = SugarDao.GetInstance())
{
//Form("Student","s")語法優化成 Form<Student>("s")
var
sable = db.Sqlable().Form<Student>(
"s"
).Join<School>(
"l"
,
"s.sch_id"
,
"l.id"
, JoinType.INNER);
if
(!
string
.IsNullOrEmpty(name))
{
sable = sable.Where(
"s.name=@name"
);
}
if
(!
string
.IsNullOrEmpty(name))
{
sable = sable.Where(
"s.id=@id or s.id=100"
);
}
if
(id > 0) {
sable = sable.Where(
"l.id in (select top 10 id from school)"
);
//where加子查詢
}
//參數
var
pars =
new
{ id = id, name = name };
pageCount = sable.Count(pars);
return
sable.SelectToList<Student>(
"s.*"
, pars);
}
}
|
四、 使用SQL或者存儲過程查詢:
爲了兼容上面知足不了的狀況因此也寫了這麼個函數以便應急之需
1
2
3
4
5
6
7
8
9
10
|
var
School = db.SqlQuery<School>(
"select * from School"
);
//獲取id
var
id = db.SqlQuery<
int
>(
"select top 1 id from School"
).Single();
//存儲過程
//var spResult = db.SqlQuery<school>("exec sp_school @p1,@p2", new { p1=1,p2=2 });
//無返回值
db.ExecuteCommand(sql);
|
添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using
(SqlSugarClient db =
new
SqlSugarClient(connStr))
//開啓數據庫鏈接
{
School s =
new
School()
{
name =
"藍翔"
};
//插入單條
var
id2 = Convert.ToInt32(db.Insert(s));
//插入多條
List<School> sList =
new
List<School>();
sList.Add(s);
var
ids = db.InsertRange(sList);
}
|
修改
1
2
3
4
|
//指定列更新
db.Update<School>(
new
{ name =
"藍翔2"
}, it => it.id == id);
//整個實體更新,注意主鍵必需爲實體類的第一個屬性
db.Update<School>(
new
School { id = id, name =
"藍翔2"
}, it => it.id == id);
|
刪除
1
2
3
4
5
6
7
|
db.Delete<School>(id);
//注意主鍵必需爲實體類的第一個屬性
db.Delete<School>(it => it.id > 100);
db.Delete<School>(
new
string
[] {
"100"
,
"101"
,
"102"
});
db.FalseDelete<school>(
"is_del"
, 100);
//假刪除
//等同於 update school set is_del=0 where id in(100)<br>
db.FalseDelete<school>(
"is_del"
, it=>it.id==100);
|
更多底層函數
1
2
3
4
5
6
7
8
9
10
|
db.ExecuteCommand(sql);
db.GetDataTable(sql);
db.GetList<Student>(sql);
db.GetSingle<Student>(sql +
" where id=1"
);
using
(SqlDataReader read = db.GetReader(sql)) { }
//事務中必定要釋放DataReader
db.GetScalar(sql);
db.GetString(sql);
db.GetInt(sql);
|
實體生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
using
(SqlSugarClient db =
new
SqlSugarClient(connStr))
//開啓數據庫鏈接
{
//根據當前數據庫生成全部表的實體類文件 (參數:SqlSugarClient ,文件目錄,命名空間)
db.ClassGenerating.CreateClassFiles(db,Server.MapPath(
"~/Models"
),
"Models"
);
//根據表名生成實體類文件
db.ClassGenerating.CreateClassFilesByTableNames(db, Server.MapPath(
"~/Models"
),
"Models"
,
"student"
,
"school"
);
//根據表名生成class字符串
var
str = db.ClassGenerating.TableNameToClass(db,
"Student"
);
//根據SQL語句生成class字符串
var
str2 = db.ClassGenerating.SqlToClass(db,
"select top 1 * from Student"
,
"student"
);
}
|
事務
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
using
(SqlSugarClient db =
new
SqlSugarClient(connStr))
//開啓數據庫鏈接
{
try
{
//開啓事務,能夠不使用事務,也可使用多個事務
db.BeginTran();
//sq1
//sql2
//sql3
}
catch
(Exception ex){
//回滾事務
db.RollbackTran();
throw
ex;
}
}
//關閉數據庫鏈接
|
無鎖查詢
當IsNoLock設爲True時,查詢生成的SQL語句表名的後面都會帶有With(Nolock)
1
2
3
4
5
6
7
8
9
10
11
|
using
(SqlSugarClient db =
new
SqlSugarClient(connStr))
//開啓數據庫鏈接
{
db.IsNoLock =
true
;
//sql xxx with(nolock)
db.IsNoLock =
false
;
//sql xxx
//sql xxx
db.IsNoLock =
true
;
//sql xxx with(nolock)
}
//關閉數據庫鏈接
|
支持多庫切換的寫法
定義一個sugarDao類來擴展SqlSugar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/// <summary>
/// 擴展SqlSugarClient
/// </summary>
public
class SugarDao
{
//禁止實例化
private SugarDao() {
}
public
static
SqlSugarClient GetInstance()
{
string
connection
=
"Server=.;uid=sa;pwd=sasa;database=SqlSugarTest"
; //這裏能夠動態根據cookies或session實現多庫切換
return
new SqlSugarClient(
connection
);
}
}
|
使用無需傳入connectionString
1
2
3
4
5
6
7
|
public
School GetSingleSchool(
int
id)
{
using (SqlSugarClient db = SugarDao.GetInstance())
{
return
db.Queryable<School>().Single(c => c.id == id);
}
}
|
3、性能測試:
10000次
1000次
10000次
.net4.52+EF 6.0+SQL12 以洗恥辱
.NET Framework 4.52+ sql12 +EF6.0 ,EF性能明顯上去了,就讓它當個冠軍吧,我也不去測試了,微軟的東西升級後性能無需質疑,在多表查詢和添刪改方面綜合下來也基本平手。
SqlSugar追求的是輕量、上手快、簡單易用對SQL的可控性,也但願你能喜歡或者提出您寶貴意見。
V1.0源碼下載地址:
http://pan.baidu.com/s/1bnmAXjh
V1.2源碼下載地址:
http://pan.baidu.com/s/1jGENyQi
更改內容:
contains查詢BUG,SQL拼接BUG
V1.3源碼下載地址:
http://pan.baidu.com/s/1kTrRbmR
更改內容:
添加 queryable/sqlable to dataTable
CACHE BUG修復
支持 int?類型這類 nullable類型
此版本穩定,多家公司正在使用
有一點須要聲名若是主鍵不是identity須要寫成 insert(obj,false)這不是BUG
主鍵位置在類中能夠任意放無需放第一個
V1.5源碼下載地址:
http://pan.baidu.com/s/1pJ8F0dt
更改內容:
一、代碼結構優化
二、刪除語法須要注意
之前刪除
db.Delete<School>(new string[] { "100", "101", "102" });
須要改爲下面這種寫法
db.Delete<School,string>(new string[] { "100", "101", "102" });
三、添加批量更新
db.Update<School, string>(new { name = "藍翔2" },new string []{"1","2"});