標籤:
SqlSugar輕量ORM
SqlSugar是一款輕量級的MSSQL ORM ,除了具有媲美ADO的效能外還具有和EF相似簡單易用的文法。
一、介簡
優點:
1、優越的效能,使用 reflection.emit + cache 接近純手工 DataReader的查詢速度
2、大量文法糖,拉姆達表達示篩選,新穎的多表查詢 ,方便的分頁等
3、支援NOLOCK查詢,提高效能
4、支援事務
5、內建實體類產生函數,無需使用第三方代碼產生器
6、簡單好用、例子齊全有問必答。
缺點:
目前只支援MSSQL,以後會全面發展
組成:
sqlSugar是由sqlSugarClientr提供統一調用模式 ,sqlSugarClientr是由5個部分組成
1、自身函數
2、實體產生
3、單表查詢
4、多表查詢
5、基類函數
二、使用教程
查詢
1、單表或者單視圖查詢:
通過調用 db.Queryable() 的相關擴充函數 輕鬆搞定單表查詢
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(); }
//存在記錄反回true,則否返回false bool isAny100 = db.Queryable<Student>().Any(c => c.id == 100); bool isAny1 = db.Queryable<Student>().Any(c => c.id == 1);
2、單表進階查詢
根據條件查詢並分頁
/// <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) { using (SugarDao db = new SugarDao()) { 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); } return qable.ToPageList(pageIndex,pageSize);//ToPageList執行資料庫並且反回結果集 } }
新容器轉換
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();//不支援匿名類轉換,也不建議使用 } }
分組查詢
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(); } }
SELECT Sex,Count=count(*) FROM Student WHERE 1=1 AND (id < 20) GROUP BY Sex --產生結果
3、多表查詢:
說到多表查詢在眾多ORM中無論是效能還是功能上都不滿意,或者說還不如用SQL,下面是我的創意,放棄了強型別寫法,讓代碼更接近SQL語句編寫,讓SQL完全可控,也解決了OMR多表的效能問題。
還有ORDERBY、GROUPBY和APPLY等,例子中就不介紹了。
拿EF來比較一下:
EF查詢:
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查詢:
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查詢:
//多表查詢 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);
4、 使用SQL或者預存程序查詢:
為了相容上面滿足不了的情況所以也寫了這麼個函數以便應急之需
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 });
添加
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); }
修改
//指定列更新 db.Update<School>(new { name = "藍翔2" }, it => it.id == id); //整個實體更新,注意主鍵必需為實體類的第一個屬性 db.Update<School>(new School { id = id, name = "藍翔2" }, it => it.id == id);
刪除
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)
db.FalseDelete<school>("is_del", it=>it.id==100);
更多底層函數
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);
代碼產生
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");}
事務
using (SqlSugarClient db = new SqlSugarClient(connStr))//開啟資料庫連接{ try{ //開啟事務,可以不使用事務,也可以使用多個事務 db.BeginTran(); //sq1 //sql2 //sql3 }catch (Exception ex){ //復原事務 db.RollbackTran(); throw ex; }}//關閉資料庫連接
無鎖查詢
當IsNoLock設為True時,產生的SQL語句表名的後面都會帶有With(Nolock)
using (SqlSugarClient db = new SqlSugarClient(connStr))//開啟資料庫連接{ db.Sqlable().IsNoLock = true; db.Sqlable().IsNoLock = false; db.Sqlable().IsNoLock = true;}//關閉資料庫連接
支援多庫切換的寫法
定義一個sugarDao類來擴充SqlSugar
/// <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
public School GetSingleSchool(int id) { using (SqlSugarClient db = SugarDao.GetInstance()) { return db.Queryable<School>().Single(c => c.id == id); } }
三、效能測試:
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/1i3EPdPj
輕量級、高效能SQL ORM 之 SqlSugar - ASP.NET