開源一個基於dotnet standard的輕量級的ORM框架-Light.Data


   還在dotnet framework 2.0的時代,當時還沒有EF,而NHibernate之類的又太復雜,並且自己也有一些特殊需求,如查詢結果直接入表、水平分表和新增數據默認值等,就試着折騰個輕量點ORM框架,就慢慢有了這個Light.Data,也一直在公司和個人的項目使用,后來陸陸續續也支持了跨數據庫並在mono中使用。到了dotnet core來臨,也嘗試移植,1.0的時候由於類庫不完善,效果不理想。2.0的基本完善了,由於個人嚴重的強迫症和拖延症,一直在折騰細節、寫單元測試和磨文檔,磨到差不多3.0快來了。。。。

    不說廢話了,Light.Data是一個輕量級的基於dotnet standard 2.0的ORM框架, 通過對實體模型類的Attribute或者配置文件進行配置與數據表的對應關系. 使用核心類DataContext對數據表進行CURD的操作.

PM> Install-Package Light.Data

支持數據庫
數據庫 說明
SqlServer 安裝Light.Data.Mssql類庫, 支持SqlServer 2008或以上
Mysql 安裝Light.Data.Mysql類庫, 支持Mysql 5.5或以上
Postgre 安裝Light.Data.Postgre類庫, 支持Postgre9.3或以上

 

 

連接配置

{
  "lightData": {
    "connections": [
      {
        "name": "mssql_db",
        "connectionString": "...",
        "providerName": "Light.Data.Mssql.MssqlProvider, Light.Data.Mssql"
      },
      {
        "name": "mysq_db",
        "connectionString": "...",
        "providerName": "Light.Data.Mysql.MysqlProvider, Light.Data.Mysql"
      }
    ]
  }
}

 

使用方式

// 直接使用
DataContext context = new DataContext("mssql");

// 創建子類
public class MyDataContext : DataContext
{
    public MyDataContext() : base("mssql")
    {

    }
}

// 創建配置子類
public class MyDataContext : DataContext
{
    public MyDataContext(DataContextOptions<MyDataContext> options) : base(options)
    {

    }
}

// 直接配置連接字符串和參數 (IServiceCollection)
service.AddDataContext<MyDataContext>(builder => {
    builder.UseMssql(connectionString);
    builder.SetTimeout(2000);
    builder.SetVersion("11.0");
}, ServiceLifetime.Transient);

// 默認配置文件配置 (IServiceCollection)
service.AddDataContext<MyDataContext>(DataContextConfiguration.Global, config => {
       config.ConfigName = "mssql";
}, ServiceLifetime.Transient);

 

對象映射

 1 [DataTable("Te_User", IsEntityTable = true)]
 2 public class TeUser
 3 {
 4     /// <summary>
 5     /// Id
 6     /// </summary>
 7     /// <value></value>
 8     [DataField("Id", IsIdentity = true, IsPrimaryKey = true)]
 9     public int Id
10     {
11         get;
12         set;
13     }
14 
15     /// <summary>
16     /// Account
17     /// </summary>
18     /// <value></value>
19     [DataField("Account")]
20     public string Account
21     {
22         get;
23         set;
24     }
25 
26     /// <summary>
27     /// Telephone
28     /// </summary>
29     /// <value></value>
30     [DataField("Telephone", IsNullable = true)]
31     public string Telephone
32     {
33         get;
34         set;
35     }
36     ....
37 }

 

子表對象關聯

在繼承類`TeUserAndExtend`中添加一個類型是`TeUserExtend`的公共屬性`Extend`, 並加上Attribute`RelationField`, 在查詢`TeUserAndExtend`時, 會把關聯的`TeUserExtend`數據也一並查出. 並支持一對多的關系
 1 [DataTable("Te_UserExtend", IsEntityTable = true)]
 2 public class TeUserExtend
 3 {
 4     [DataField("Id", IsIdentity = true, IsPrimaryKey = true)]
 5     public int Id
 6     {
 7         get;
 8         set;
 9     }
10 
11     [DataField("MainId")]
12     public int MainId
13     {
14         get;
15         set;
16     }
17     
18     [DataField("Data", IsNullable = true)]
19     public string Data
20     {
21         get;
22         set;
23     }
24 }
25 
26 
27 public class TeUserAndExtend : TeUser
28 {
29     [RelationField("Id", "MainId")]
30     public TeUserExtend Extend
31     {
32         get;
33         set;
34     }
35 }

 

基本操作

  • 基本CURD
  • 批量CUD
  • 支持事務處理
  • 支持數據字段默認值和自動時間戳
  • 支持數據字段讀寫控制
  • 查詢結果指定類或匿名類輸出
  • 查詢直接插入數據表
 1 var context = new DataContext();
 2 // 查詢單個數據
 3 var item = context.Query<TeUser>().Where(x => x.Id == 10).First();
 4 // 查詢集合數據
 5 var list = context.Query<TeUser>().Where(x => x.Id > 10).ToList();
 6 // 新增數據
 7 var user = new TeUser() {
 8     Account = "foo",
 9     Password = "bar"
10 };
11 context.Insert(user);
12 // 修改數據
13 user.Password = "bar1";
14 context.Update(user);
15 // 刪除數據
16 context.Delete(user);

 

數據匯總

  • 單列數據直接匯總
  • 多列數據分組匯總
  • 格式化分組字段
  • 匯總數據直接插入數據表
 1 // 普通匯總
 2 var list = context.Query<TeUser> ()
 3                   .Where (x => x.Id >= 5)
 4                   .Aggregate (x => new LevelIdAgg () {
 5                       LevelId = x.LevelId,
 6                       Data = Function.Count ()
 7                    })
 8                   .ToList ();
 9 
10 // 日期格式化統計
11 var list = context.Query<TeUser> ()
12                   .Aggtrgate (x => new RegDateFormatAgg () {
13                       RegDateFormat = x.RegTime.ToString("yyyy-MM-dd"),
14                       Data = Function.Count ()
15                    })
16                   .ToList ();    

 

連表查詢

  • 多表連接, 支持內連接, 左連接和右連接
  • 支持查詢結果和匯總數據連接
  • 連接查詢結果指定類或匿名類輸出
  • 連接查詢結果直接插入數據表
 1 // 內連接
 2 var join = context.Query<TeUser> ()
 3                   .Join<TeUserExtend>((x,y) => x.Id == y.Id);
 4 
 5 // 統計結果連接實體表             
 6 var join = context.Query<TeMainTable>()
 7                   .GroupBy(x => new {
 8                       MId = x.MId,
 9                       Count = Function.Count(),
10                    })
11                   .Join<TeSubTable>((x, y) => x.MId == y.Id);

 

執行SQL語句

  • 直接使用SQL語句和存儲過程
  • 支持對象參數
  • 查詢結果指定類或匿名類輸出
  • 存儲過程支持output參數
 1 // 普通參數
 2 var sql = "update Te_User set NickName=@P2 where Id=@P1";
 3 var ps = new DataParameter[2];
 4 ps[0] = new DataParameter("P1", 5);
 5 ps[1] = new DataParameter("P2", "abc");
 6 var executor = context.CreateSqlStringExecutor(sql, ps);
 7 var ret = executor.ExecuteNonQuery();
 8 
 9 // 對象參數
10 var sql = "update Te_User set NickName={nickname} where Id={id}";
11 var executor = context.CreateSqlStringExecutor(sql, new { nickname = "abc", id = 5 });
12 var ret = executor.ExecuteNonQuery();

單元測試

項目使用xUnit做單元測試,測試代碼地址:https://github.com/aquilahkj/Light.Data2/tree/master/test

每種數據庫均有300多組1000多用例的測試,覆蓋大部分代碼。

 

性能測試

目前只跟EF Core在同一電腦的Docker上的Sql Server 2017 for linux中做簡單的增刪改查性能對比測試,代碼地址 https://github.com/aquilahkj/OrmTest

1000次的增刪改和單條數據查詢

共5輪,每輪1000條的增刪改和1000條數據查詢

EF的測試結果

Light.Data測試結果

從對比看,查詢性能兩者差不多,新增性能Light.Data稍微占優,批量更新也稍微占優。

另外值得一提的是Postgre,批量增刪改性能比Sql Server快2,3倍,看來以后也要好好研究一下。

 以上均是非嚴謹測試,僅供參考。

 

最后

本文只是簡單的介紹,具體使用方法可以查看文檔和參考測試用例,如有需要會寫具體使用的文章。

Light.Data這個項目這么多年來個人一直維護,也在不斷優化,不斷成長,但一直養在深閨,好不容易折騰開源也是希望能共享出去,給有需要的朋友多個選擇,同時也是給自己這么多年碼農的見證。

雖然現在ORM的框架非常非常多,也不是什么熱門新鮮事物,但總歸是個基礎的東西。

如果有朋友喜歡,不妨試試,可以的話,給個Star,十分歡迎意見或建議 :D


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM