輕量ORM-SqlRepoEx (一)SqlRepoEx介紹
一、SqlRepo專案
對於資料訪問,在.Net下,有很多選擇,比如EF,但EF使用起來,不是很方便的。以前一直使用Atk.Expression庫+System.Data.SqlClient來進行資料操作,總體來說希望有這樣一個ORM:
1、能方便支援Mysql、SQLServert等資料庫;
2、框架不能複雜、功能強大但不需要犧牲資料訪問速度;
3、能使用Lambda表示式,以方便使用.Net強大的功能;
4、使用強型別而不是弱型別構建;
5、能在需要轉換成SQL語句;
6、易用Lambda表示式來構建拼接SQL語句,減少魔法字串的出現。
SqlRepo專案是一個.NET庫,用於構建帶有Lambda表示式的SQL語句,並將結果對映到物件的工具。在使用SqlRepo中,發現基本能達到要求。但在使用中,發現不少bug,同時功能上不是特別完善,所以Fork了一個,強化其功能,將其命名為SqlRepoEx。並增加如下(1)自定特性;(2)、動態指定查詢源;(3)解決拼接語句,使用where以外方法時,缺少Where子句時的錯誤;(4)、增加操作時,不再受限於例項必需有Id的自增自段;(5)、表達示使時,可直接使用變數;
二、簡單的例子
1、有如下業務類
public class ToDo { public DateTime CreatedDate { get; set; } public bool IsCompleted { get; set; } public string Task { get; set; } }
2、使用SqlRepoEx查詢
var repository = RepoFactory.Create<ToDo>(); var results = repository.Query() .Select(e => e.Id, e => e.Task, e => e.CreatedDate) .Where(e => e.IsCompleted == false) .Go();
3、在2中,如果與資料庫連線訪問,可以直接返回一個IEnumerable<ToDo>的結果集,如果只需要獲取SqL語句只需要:
string querystr = repository.Query() .Select(e => e.Id, e => e.Task, e => e.CreatedDate) .Where(e => e.IsCompleted == false) .Sql(); querystr結果為:"SELECT [dbo].[ToDo].[Id] , [dbo].[ToDo].[Task], [dbo].[ToDo].[CreatedDate] FROM [dbo].[ToDo] WHERE ([dbo].[ToDo].[IsCompleted] = 0)"
三、關於SqlRepoEx效能,在原生的SqlRepo有對其進行對比測試:
比較庫:
1、SqlRepo
2、Dapper
3、EF Core 2.0
測試環境:
1、每個測試都執行在包含5萬條記錄的SQL資料庫上。測試執行105次,前5個測試被忽略,以支援JIT和任何動態IL。
2、測試機器是一個在i7 7700 k上執行4個核心的VM。最後一次是在2018年3月4日。
測試:選擇返回所有記錄(Select All Records)
庫 | 最好結果(ms) | 總時間 |
---|---|---|
Dapper | 51.03ms | 6250.34ms |
EF Core | 163.11ms | 19874.59ms |
SqlRepo | 50.34ms | 6260.17ms |
測試:選擇一條記錄(Select TOP 1)
庫 | 最好結果(ms) | 總時間 |
---|---|---|
Dapper | 0.3ms | 73.73ms |
EF Core | 0.66ms | 42.85ms |
SqlRepo | 0.35ms | 40.16ms |
測試:Select TOP 5000
庫 | 最好結果(ms) | 總時間 |
---|---|---|
Dapper | 3.91ms | 533ms |
EF Core | 9.81ms | 2082.93ms |
SqlRepo | 4ms | 526.43ms |
測試:動態資料測試
庫 | 最好結果(ms) | 總時間 |
---|---|---|
Dapper | 13.16ms | 2382.85ms |
EF Core | 39.93ms | 5106.13ms |
SqlRepo | 12.74ms | 2284.85ms |
具體測試原始碼見 https://github.com/SqlRepo/Benchmarks