支持.Net/.Net Core/.Net Framework,可以部署在Docker, Windows, Linux, Mac。 常見的ORM技術(比如:Entity Framework,Dapper,SqlSugar,NHibernate,等…),它們不是在做Sql語句的程式化變種,就是在做Sq ...
支持.Net/.Net Core/.Net Framework,可以部署在Docker, Windows, Linux, Mac。
本文提供了一種結合“原生Sql+輕量級ORM”操作各類資料庫的工具。該工具幾乎只使用了一個方法/函數,卻實現了幾乎所有的數據操作功能。它已成功應用到了人工智慧、產業互聯網、智慧醫療、等多個大型項目上。
此工具在IDataAccess介面中提供。
IDataAccess所在的命名空間是:DeveloperSharp.Framework.QueryEngine(需從NuGet引用DeveloperSharp包)
它主要提供瞭如下四大功能:
(1) 執行Sql語句
(2) 執行Sp存儲過程
(3) 創建參數(輸入/輸出/返回)
(4) 事務
它初始化的代碼如下:
若是在.Net Core環境下,代碼如下:
using DeveloperSharp.Framework.QueryEngine; -------------------------- //在Startup.cs或Program.cs文件中進行 Services.AddTransient<IDataAccess>((t) => { DatabaseInfo DIF; DIF.DatabaseType = DatabaseType.SQLServer; //設置資料庫類型 DIF.ConnectionString = "Server=localhost;Database=YZZ;Uid=sa;Pwd=123"; return DataAccessFactory.Create(DIF); });
若是在.Net Framework環境下,代碼如下:
using DeveloperSharp.Framework.QueryEngine; -------------------------- DatabaseInfo DIF; DIF.DatabaseType = DatabaseType.SQLServer; //設置資料庫類型 DIF.ConnectionString = "Server=localhost;Database=YZZ;Uid=sa;Pwd=123"; IDataAccess IDA = DataAccessFactory.Create(DIF);
註意:通過對DatabaseType屬性的設定,提供了對所有種類資料庫的支持(包括:MySql、Oracle、PostgreSQL、SqlServer、Sqlite、Firebird、達夢、以及人大金倉KingbaseES、神舟通用, 南大通用, 翰高, Access、等)
【示例1:查詢】
下麵,首先直接給出一個“查詢多數據+選出單數據+參數”的使用示例,代碼如下:
//查詢多數據 var Students1 = IDA.SqlExecute<stu>("select * from t_Student"); //查詢多數據(帶參數) var Students2 = IDA.SqlExecute<stu>("select * from t_Student where Id>@IdMin and Name like @LikeName", new { IdMin = 2, LikeName = "%周%" }); //另一種寫法1 var IdMin = IDA.CreateParameterInput("IdMin", DbType.Int32, 2); var LikeName = IDA.CreateParameterInput("LikeName", DbType.String, 50, "%周%"); var Students3 = IDA.SqlExecute<stu>("select * from t_Student where Id>@IdMin and Name like @LikeName", LikeName, IdMin); //另一種寫法2 var Students4 = IDA.SqlExecute<stu>("select * from t_Student").Where(t => t.Id > 2 && t.Name.Contains("周")); //選出單數據 var OneStudent = Students2.FirstOrDefault();
其中stu實體類代碼如下形式:
//此實體類中的Id、Name、Age、Birth、MyLevel屬性名,要與數據表中的欄位名一一對應 public class stu { public int? Id { get; set; }//資料庫中該欄位若存在Null值,類型後需要加問號? public string Name { get; set; } public int? Age { get; set; } public DateTime? Birth { get; set; } public Level? MyLevel { get; set; }//也可以使用枚舉,會自動轉換 } public enum Level { Student=100,//學生 Teacher=200,//老師 Manager=300,//管理員 Principle=400//校長 }
註意:(1)DbType類型的命名空間是System.Data
(2)若沒有定義stu實體類,也可以用dynamic替代
【示例2:分頁】
承接上面“示例1”的代碼,若我們要對Students1、Students2進行分頁操作(比如:每頁20條,取出第5頁),相關代碼如下:
using DeveloperSharp.Extension;//調用“分頁功能”需要引用此命名空間 -------------------------- var Page1 = Students1.PagePartition(20, 5); var Page2 = Students2.PagePartition(20, 5); //一氣呵成的寫法 var Page3 = IDA.SqlExecute<stu>("select * from t_Student").PagePartition(20, 5);
分頁後獲得的PagePiece對象中所包含的各類屬性/參數,可參看這篇文章:高效分頁
【示例3:增/刪/改】
前面談完“查詢”,我們接下來談談“增/刪/改”的使用方式,下麵是一個“修改數據+參數+事務”的使用示例:
try { //開啟事務 IDA.TransactionBegin(); //修改數據(多語句) int affectedRows1 = IDA.SqlExecute("insert into t_Student(Name,Age)values('ww','96');update t_Student set Age=100 where Id=1006"); //修改數據(帶參數) int affectedRows2 = IDA.SqlExecute("insert into t_Student(Name,Age)values(@N,@A)", new { N = "孫悟空", A = 200 }); //另一種寫法 var NewAge = IDA.CreateParameterInput("NewAge", DbType.Int32, 200); var NewName = IDA.CreateParameterInput("NewName", DbType.String, 50, "孫悟空"); int affectedRows3 = IDA.SqlExecute("insert into t_Student(Name,Age)values(@NewName,@NewAge)", NewName, NewAge); //完成事務 IDA.TransactionCommit(); } catch { //回滾事務 IDA.TransactionRollBack(); }
【示例4:輸出參數】
前面幾個示例都只用到了“輸入參數”,下麵我們看看“輸出參數”怎麼使用,示例代碼如下:
var op1 = IDA.CreateParameterOutput("TotalCount", DbType.Int32);//此項為輸出參數 var op2 = IDA.CreateParameterOutput("MyName", DbType.String, 50);//此項為輸出參數 //以下sql語句混雜了多個“輸入”與“輸出”參數,註意看 IDA.SqlExecute("insert into Friend(Birth,Name,height)values(@B,@N,@h);" + "select @TotalCount=count(*) from Friend;" + "select @MyName=Name from Friend where Id=@Id", new { N = "楊小偉", B = "1999-02-28 12:03:45", h = 11.023, Id = 2 }, op1, op2); int tc = Convert.ToInt32(op1.Value); string mn = op2.Value.ToString();
【示例5:存儲過程】
最後,我們來談談如何調用存儲過程。我們創建一個存儲過程,它帶有輸入、輸出、返回三種類型的參數,代碼如下:
CREATE PROCEDURE Test5 @B as datetime, @N as nvarchar(50), @h as float, @TotalCount as int output, @MyName as nvarchar(50) output, @Id as int AS BEGIN insert into Friend(Birth,Name,height)values(@B,@N,@h); select @TotalCount=count(*) from Friend; select @MyName=Name from Friend where Id=@Id; return @TotalCount+100; END
調用該存儲過程的示例代碼如下:
var op1 = IDA.CreateParameterOutput("TotalCount", DbType.Int32);//輸出參數 var op2 = IDA.CreateParameterOutput("MyName", DbType.String, 50);//輸出參數 var op3 = IDA.CreateParameterReturn();//返回參數 IDA.SpExecute("Test5", new { N = "楊小偉", B = "1999-02-28 12:03:45", h = 11.023, Id = 2 }, op1, op2, op3); int tc = Convert.ToInt32(op1.Value); string mn = op2.Value.ToString(); int ret = Convert.ToInt32(op3.Value);
學習+靈活使用以上5個示例,就能滿足幾乎所有的數據操作需求。
另外,你有沒有發現,上述所有的數據操作幾乎只用了一個方法來實現:SqlExecute/ SqlExecute<T>
-----------------------
【後記】
有讀者問到:本“工具說明”文章過於簡單,缺乏全面、細節功能的詳細介紹,所以很難依據本文內容做全面學習及後續開發。
回答如下:其實不然,原因有三。
(1)有一定資料庫開發經驗的人應該能看出,本文介紹的內容,已經能滿足絕大多數情況下資料庫操作的功能需求。
(2)不像其它第三方工具有很多非標的自定義語法(這些“自定義語法”需要單獨學習,而且往往並不符合微軟規範),本工具順應了原生.Net/C#、Linq、Sql語言的協調性(從幾個示例就能看出),所以無需付出更多學習時間,自己動手簡單用一用,各種功能就能馬上實現。
舉例:本文示例中並沒有給出對結果集進行“排序操作”的代碼。但你若會用Linq,順應的應該馬上能猜出如何進行排序?
(3)已有讀者依據本文內容把技術採用到了具體項目上。
-----------------------
IDataAccess內功能方法詳細說明(輔助參考):
SqlExecute<T> (非同步為:SqlExecuteAsync<T>) 聲明:IEnumerable<T> SqlExecute<T>(string cmdText, params IDataParameter[] Params) where T : class, new() 用途:執行Sql語句(Select類) 參數:(1)string cmdText -- Sql語句 (2)params IDataParameter[] Params -- 參數組 返回:IEnumerable<T> -- 多數據結果集 SqlExecute<T> (非同步為:SqlExecuteAsync<T>) 聲明:IEnumerable<T> SqlExecute<T>(string cmdText, object InputParams, params IDataParameter[] Params) where T : class, new() 用途:執行Sql語句(Select類) 參數:(1)string cmdText -- Sql語句 (2)object InputParams -- 輸入參數對象 (3)params IDataParameter[] Params -- 參數組 返回:IEnumerable<T> -- 多數據結果集 SqlExecute (非同步為:SqlExecuteAsync) 聲明:int SqlExecute(string cmdText, params IDataParameter[] Params) 用途:執行Sql語句(Insert/Update/Delete類) 參數:(1)string cmdText -- Sql語句 (2)params IDataParameter[] Params -- 參數組 返回:int -- 受影響的行數 SqlExecute (非同步為:SqlExecuteAsync) 聲明:int SqlExecute(string cmdText, object InputParams, params IDataParameter[] Params) 用途:執行Sql語句(Insert/Update/Delete類) 參數:(1)string cmdText -- Sql語句 (2)object InputParams -- 輸入參數對象 (3)params IDataParameter[] Params -- 參數組 返回:int -- 受影響的行數 SpExecute<T> (非同步為:SpExecuteAsync<T>) 聲明:IEnumerable<T> SpExecute<T>(string cmdText, params IDataParameter[] Params) where T : class, new() 用途:執行Sp存儲過程(Select類) 參數:(1)string cmdText -- Sp存儲過程名 (2)params IDataParameter[] Params -- 參數組 返回:IEnumerable<T> -- 多數據結果集 SpExecute<T> (非同步為:SpExecuteAsync<T>) 聲明:IEnumerable<T> SpExecute<T>(string cmdText, object InputParams, params IDataParameter[] Params) where T : class, new() 用途:執行Sp存儲過程(Select類) 參數:(1)string cmdText -- Sp存儲過程名 (2)object InputParams -- 輸入參數對象 (3)params IDataParameter[] Params -- 參數組 返回:IEnumerable<T> -- 多數據結果集 SpExecute (非同步為:SpExecuteAsync) 聲明:int SpExecute(string cmdText, params IDataParameter[] Params) 用途:執行Sp存儲過程(Insert/Update/Delete類) 參數:(1)string cmdText -- Sp存儲過程名 (2)params IDataParameter[] Params -- 參數組 返回:int -- 受影響的行數 SpExecute (非同步為:SpExecuteAsync) 聲明:int SpExecute(string cmdText, object InputParams, params IDataParameter[] Params) 用途:執行Sp存儲過程(Insert/Update/Delete類) 參數:(1)string cmdText -- Sp存儲過程名 (2)object InputParams -- 輸入參數對象 (3)params IDataParameter[] Params -- 參數組 返回:int -- 受影響的行數