一个开源的 ORM 框架 - Light.Data





5.00/5 (3投票s)
开源项目 Light.Data 介绍
引言
Light.Data
是一个基于 dotnet standard 2.0
的轻量级 ORM 框架,通过实体模型类的 Attribute
或配置文件关联数据表。 使用核心类 DataContext
对表进行 CRUD
操作。
PM> Install-Package Light.Data
支持的数据库
数据库 | 引言 |
SqlServer | 需要安装 nuget 安装 Light.Data.Mssql 库,支持 SqlServer 2008 或以上 |
Mysql | 需要安装 nuget 安装 Light.Data.Mysql 库,支持 Mysql5.5 或以上 |
Postgre | 需要安装 nuget 安装 Light.Data.Postgre 库,支持 PostgreSQL9.3 或以上 |
如何使用
数据库配置
{
"lightData": {
"connections": [
{
"name": "mssql_db",
"connectionString": "...",
"providerName": "Light.Data.Mssql.MssqlProvider, Light.Data.Mssql"
},
{
"name": "mysql_db",
"connectionString": "...",
"providerName": "Light.Data.Mysql.MysqlProvider, Light.Data.Mysql"
}
]
}
}
使用方法
// direct use
DataContext context = new DataContext("mssql");
// create subclass
public class MyDataContext : DataContext
{
public MyDataContext() : base("mssql")
{
}
}
// create subclass with options
public class MyDataContext : DataContext
{
public MyDataContext(DataContextOptions<MyDataContext> options) : base(options)
{
}
}
// direct config connect string and params (IServiceCollection)
service.AddDataContext<MyDataContext>(builder => {
builder.UseMssql(connectionString);
builder.SetTimeout(2000);
builder.SetVersion("11.0");
}, ServiceLifetime.Transient);
// use default configuration file to config (IServiceCollection)
service.AddDataContext<MyDataContext>(DataContextConfiguration.Global, config => {
config.ConfigName = "mssql";
}, ServiceLifetime.Transient);
对象映射
[DataTable("Te_User", IsEntityTable = true)]
public class TeUser
{
/// <summary>
/// Id
/// </summary>
/// <value></value>
[DataField("Id", IsIdentity = true, IsPrimaryKey = true)]
public int Id
{
get;
set;
}
/// <summary>
/// Account
/// </summary>
/// <value></value>
[DataField("Account")]
public string Account
{
get;
set;
}
/// <summary>
/// Telephone
/// </summary>
/// <value></value>
[DataField("Telephone", IsNullable = true)]
public string Telephone
{
get;
set;
}
....
}
子表映射
在派生类 TeUserAndExtend
中,添加一个 public
属性 Extend
,其类型为 TeUserExtend
,并添加 Attribute RelationFieldAttribute
。 在查询 TeUserAndExtend
时,关联的 TeUserExtend
数据也将被检测到,并且也支持一对多
[DataTable("Te_UserExtend", IsEntityTable = true)]
public class TeUserExtend
{
[DataField("Id", IsIdentity = true, IsPrimaryKey = true)]
public int Id
{
get;
set;
}
[DataField("MainId")]
public int MainId
{
get;
set;
}
[DataField("Data", IsNullable = true)]
public string Data
{
get;
set;
}
}
public class TeUserAndExtend : TeUser
{
[RelationField("Id", "MainId")]
public TeUserExtend Extend
{
get;
set;
}
}
基本操作
- 基本 CRUD
- 批量 CUD
- 支持事务处理
- 支持数据字段默认值和自动时间戳
- 支持数据字段读写控制
- 查询结果指定类或匿名类输出
- 将查询结果直接插入到数据表中
var context = new DataContext();
// query single data
var item = context.Query<TeUser>().Where(x => x.Id == 10).First();
// query collection datas
var list = context.Query<TeUser>().Where(x => x.Id > 10).ToList();
// create date
var user = new TeUser() {
Account = "foo",
Password = "bar"
};
context.Insert(user);
// update data
user.Password = "bar1";
context.Update(user);
// delete data
context.Delete(user);
数据聚合
- 单列数据直接聚合
- 多列数据分组聚合
- 格式化分组字段
- 将聚合数据直接插入到数据表中
// basic
var list = context.Query<TeUser> ()
.Where (x => x.Id >= 5)
.GroupBy (x => new LevelIdAgg () {
LevelId = x.LevelId,
Data = Function.Count ()
})
.ToList ();
// date format
var list = context.Query<TeUser> ()
.GroupBy (x => new RegDateFormatAgg () {
RegDateFormat = x.RegTime.ToString("yyyy-MM-dd"),
Data = Function.Count ()
})
.ToList ();
Join-Table 查询
- 多表连接,支持内连接,左连接和右连接
- 支持查询结果和聚合数据一起连接
- 连接查询结果指定类或匿名类输出
- 将连接查询结果直接插入到数据表中
// inner join
var join = context.Query<TeUser> ()
.Join<TeUserExtend>((x,y) => x.Id == y.Id);
// aggregate data join entity table
var join = context.Query<TeMainTable>()
.GroupBy(x => new {
MId = x.MId,
Count = Function.Count(),
})
.Join<TeSubTable>((x, y) => x.MId == y.Id);
执行 SQL
- 直接使用 SQL 和存储过程
- 支持对象参数
- 查询结果指定类或匿名类输出
- 存储过程支持使用输出参数
// basic parameter
var sql = "update Te_User set NickName=@P2 where Id=@P1";
var ps = new DataParameter[2];
ps[0] = new DataParameter("P1", 5);
ps[1] = new DataParameter("P2", "abc");
var executor = context.CreateSqlStringExecutor(sql, ps);
var ret = executor.ExecuteNonQuery();
// object parameter
var sql = "update Te_User set NickName={nickname} where Id={id}";
var executor = context.CreateSqlStringExecutor(sql, new { nickname = "abc", id = 5 });
var ret = executor.ExecuteNonQuery();
单元测试
该项目使用 xUnit 进行单元测试,测试代码地址为:https://github.com/aquilahkj/Light.Data2/tree/master/test
每个数据库都有 300 多组测试,包含 1000 个用例,涵盖了大部分代码。
性能测试
目前,仅在同一台计算机的 Docker SQL Server 2017 for Linux 上使用 EF Core 做简单的 CRUD 性能测试,代码地址 https://github.com/aquilahkj/OrmTest。
1000 次 CUD 和单数据查询。
总共 5 轮,每轮 1000 次 CUD 和 1000 次数据查询。
EF 测试结果
Light.Data
测试结果
从对比来看,查询性能几乎相同,插入性能 Light.Data
略好,批量更新也略好。
本文仅作简要介绍,具体使用方法可以参考文档和测试用例。