与 Dapper 比较

nicye2021年2月4日大约 5 分钟约 1503 字

与 Dapper 比较

众所周知 Dapper 是 .NET 下最轻最快的 ORM,它是喜欢写 SQL 码农的福音,相对于 SqlHelper 它更加方便,据统计 10 个 .NETer 有 9 个 用过 Dapper。

这篇文章为准备使用 FreeSql 的朋友解惑,对比 Dapper 有何优势,为什么要使用 FreeSql?希望本文内容对大家有所帮助。

关于性能(输了)

Dapper + SQL 是大家一般所用的方式,性能对比主要体现在两个阶段:

1、执行前,表达式树解析,拼接 SQL 的消耗:

  • Dapper 几乎没有消耗;
  • FreeSql 会存在递归解析、对象拆箱等操作;

从项目工程可维护性角度看,这一点性能损失是能被容忍的,请看下面的测试结果。

2、执行后,返回数据转换为 List:

  • Dapper 采用 Emit 构造委托并缓存,性能接近原生代码;
  • FreeSql 采用 ExpressionTree 构造委托并缓存,为了映射类型更加易用使用了一点装箱操作,性能比 Dapper 略低;
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19044
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=6.0.100
  [Host]     : .NET Core 5.0.11 (CoreCLR 5.0.1121.47308, CoreFX 5.0.1121.47308), X64 RyuJIT DEBUG
  Job-LEQVAV : .NET Core 5.0.11 (CoreCLR 5.0.1121.47308, CoreFX 5.0.1121.47308), X64 RyuJIT DEBUG

BuildConfiguration=Debug  InvocationCount=1  UnrollFactor=1
MethodsizeMeanErrorStdDevMedianRank
FreeSqlSelect1271.6 us14.03 us41.16 us272.6 us2
SqlSugarSelect1323.5 us15.75 us45.18 us314.9 us3
EfCoreSelect1392.8 us17.61 us49.39 us376.2 us4
DapperSelete1215.9 us11.88 us33.52 us213.8 us1
FreeSqlSelect500811.8 us18.86 us55.02 us798.5 us5
SqlSugarSelect5001,148.6 us53.94 us157.34 us1,116.3 us7
EfCoreSelect5001,310.2 us89.90 us262.25 us1,219.3 us8
DapperSelete500942.1 us18.46 us42.05 us931.1 us6

如上测试 Top1、Top500 单表查询水平结果

测试注意 IFreeSql 是单例模式设计,请勿重复创建,测试前请预热

测试结果是 us 级别的慢,能接受,因为数据库的上限并发瓶颈比较低(几万的水平),应用程序中的这一点消耗远不是问题。

最怕方法或设计错了导致的慢,那慢就是秒级以上的慢了,无力回天。

关于功能(赢了)

Dapper 几乎只有执行 SQL 的功能,市面上有一些基于 Dapper 做的轻量级 ORM,可以对实体对象进行 CRUD 操作,支持的数据库有限。

Dapper 在功能方面几乎完败于 FreeSql,例如:

  • CodeFirst:Dapper 不支持;
  • 类型映射:Dapper 在不同数据库之间的类型映射容易报错。比如实体类属性是 string,但是数据库类型是 int,非常容易报错,这不是杠,真实项目中有很多非等映射类型存在;
  • 表达式树:Dapper 不支持导航属性、自定义解析、以及特别的解析;
  • 导航属性:Dapper 不支持;
  • 批量插入:Dapper 需要自己写 SQL 或者引入第三方包,FreeSql 自带集成;
  • 批量更新:Dapper 需要自己写 SQL,FreeSql 自带集成;
  • 工作单元:Dapper 需要引入第三方包,FreeSql 自带集成;
  • 读写分离:??
  • 全局过滤:??

等等。。。

FreeSql 赢在功能丰富,给使用者提供最大便利,你准备好入坑了吗?

如何接入(老项目)

如果你的项目正在使用 Dapper,请看以下成本最低的接入方法。

FreeSql 支持调用 SQL/存储过程,同时也为 IDbConnection/IDbTransaction 提供扩展方法 Select/Delete/Insert/Update/InsertOrUpdate。

第一步:以数据库 SqlServer 访问为例,只需要安装已经划分好的小包:

dotnet add package FreeSql.Provider.SqlServer

or

Install-Package FreeSql.Provider.SqlServer

第二步:建立实体类

class TestConnectionExt {
    public Guid id { get; set; }
    public string title { get; set; }
    public DateTime createTime { get; set; } = DateTime.Now;
}

第三步:开始 CRUD

using (var conn = new SqlConnection(connectString)) {
    var list = conn.Select<TestConnectionExt>().Where(a => a.id == item.id).ToList();
}

using (var conn = new SqlConnection(connectString)) {
    var item = new TestConnectionExt { title = "testinsert" };
    var affrows = conn.Insert(item).ExecuteAffrows();
}

using (var conn = new SqlConnection(connectString)) {
    var affrows = conn.Update<TestConnectionExt>()
        .Where(a => a.Id == xxx)
        .Set(a => a.title, "testupdated")
        .ExecuteAffrows();
}

using (var conn = new SqlConnection(connectString)) {
    var affrows = conn.Delete<TestConnectionExt>()
        .Where(a => a.Id == xxx)
        .ExecuteAffrows();
}

添加或更新:

using (var conn = new SqlConnection(connectString)) {
    var affrows = conn.InsertOrUpdate<TestConnectionExt>()
        .SetSource(item)
        .ExecuteAffrows();
}

如上添加、删除、修改、查询,已经支持实体类操作,并且支持批量插入、批量更新、批量删除、多表查询、导航属性查询。

可以享用 FreeSql 几乎所有功能。

思考:使用这种 API 貌似可以很轻松的接入到 abp vnext 中?

学习指南

FreeSql 是一款功能强大的对象关系映射(O/RM)组件,支持 .NET Core 2.1+、.NET Framework 4.0+ 以及 Xamarin。

  • 🛠 支持 CodeFirst 模式,即便使用 Access 数据库也支持数据迁移;
  • 💻 支持 DbFirst 模式,支持从数据库导入实体类,或使用实体类生成工具生成实体类;
  • ⛳ 支持 深入的类型映射,比如 PgSql 的数组类型等;
  • ✒ 支持 丰富的表达式函数,以及灵活的自定义解析;
  • 🏁 支持 导航属性一对多、多对多贪婪加载,以及延时加载;
  • 📃 支持 读写分离、分表分库、过滤器、乐观锁、悲观锁;
  • 🌳 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access 等数据库;

基础

进阶

高级