Skip to content

Dapper比较

2881099 edited this page Mar 10, 2023 · 16 revisions

众所周知 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
Method size Mean Error StdDev Median Rank
FreeSqlSelect 1 271.6 us 14.03 us 41.16 us 272.6 us 2
SqlSugarSelect 1 323.5 us 15.75 us 45.18 us 314.9 us 3
EfCoreSelect 1 392.8 us 17.61 us 49.39 us 376.2 us 4
DapperSelete 1 215.9 us 11.88 us 33.52 us 213.8 us 1
FreeSqlSelect 500 811.8 us 18.86 us 55.02 us 798.5 us 5
SqlSugarSelect 500 1,148.6 us 53.94 us 157.34 us 1,116.3 us 7
EfCoreSelect 500 1,310.2 us 89.90 us 262.25 us 1,219.3 us 8
DapperSelete 500 942.1 us 18.46 us 42.05 us 931.1 us 6

如上测试 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 packages 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/ClickHouse/QuestDB 等数据库;

基础

进阶

高级

Clone this wiki locally