Ahm*_*med 27 c# entity-framework dapper
我是新手使用ORM处理数据库,目前我正在制作一个新项目,我必须决定是否使用Entity Framework或Dapper.我读了许多文章说Dapper比实体框架更快.
所以我使用Dapper创建了两个简单的原型项目,另一个使用Entity Framework和一个函数从一个表中获取所有行.表格架构如下图所示

以及两个项目的代码如下
对于Dapper项目
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Emp> emplist = cn.Query<Emp>(@"Select * From Employees");
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
Run Code Online (Sandbox Code Playgroud)
实体框架项目
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
Run Code Online (Sandbox Code Playgroud)
经过多次尝试上面的代码只有我第一次运行项目时,dapper代码会更快,在这第一次之后我总是从实体框架项目中获得更好的结果我还尝试了以下关于实体框架项目的语句来阻止懒惰装载
hrctx.Configuration.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)
但是,除了第一次以外,EF的表现仍然相同.
虽然网上的所有文章都相反,但任何人都能给我解释或指导EF在这个样本中的速度更快
更新
我已经改变了实体样本中的代码行
IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();
Run Code Online (Sandbox Code Playgroud)
使用某些文章中提到的AsNoTracking会停止实体框架缓存,停止缓存后,dapper样本表现更好,(但不是很大的区别)
Ami*_*shi 35
ORM(对象关系映射器)是一种在应用程序和数据源之间创建层的工具,它返回关系对象而不是(就您正在使用的c#而言)ADO.NET对象.这是每个ORM所做的基本事情.
为此,ORM通常执行查询并将返回的映射映射DataReader到POCO类.小巧玲珑限于此.
为了进一步扩展这一点,一些ORM(也称为"完整ORM")可以执行更多操作,例如为您创建查询以使您的应用程序数据库独立,为将来的调用缓存数据,为您管理工作单元等等.所有这些都是很好的工具,为ORM增添了价值; 但它带有成本.实体框架属于这一类.
要生成查询,EF必须执行其他代码.缓存可提高性能,但管理缓存需要执行其他代码.对于工作单元和EF提供的任何其他附加功能也是如此.所有这些都可以节省您编写额外代码的费用,EF 可以节省成本.
而成本就是性能.由于Dapper做了非常基本的工作,它更快; 但你必须写更多的代码.由于EF做的远远不止于此,它会慢一点; 但你必须少写代码.
那么为什么你的测试结果反应相似?
因为您正在执行的测试无法比较.
如上所述,完整的ORM具有许多良好的特征; 其中一个是UnitOfWork.跟踪是UoW的责任之一.首次请求对象(SQL查询)时,会导致数据库往返.然后将此对象保存在内存缓存中.完整ORM跟踪对此已加载对象所做的更改.如果再次请求相同的对象(在包含加载对象的同一UoW范围内的其他SQL查询),则它们不会执行数据库往返.相反,它们会从内存缓存中返回对象.这样,节省了相当多的时间.
Dapper不支持此功能,导致它在测试中执行速度较慢.
但是,此优势仅适用于多次加载相同对象的情况.此外,如果内存中加载的对象数太多,这将减慢完整的ORM,因为检查内存中的对象所需的时间会更长.再次,这种好处取决于用例.
I read many articles which says that Dapper is faster than Entity Framework
互联网上大多数基准测试的问题在于,它们将EF Linq与Dapper进行了比较。这也是您所做的。这不公平。自动生成的查询(EF)通常不等于优秀开发人员编写的查询。
这个,
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
Run Code Online (Sandbox Code Playgroud)
应该用这个代替。
IEnumerable<Employee> emplist = hrctx.Employees.FromSql(@"Select * From Employees").AsNoTracking();
Run Code Online (Sandbox Code Playgroud)
编辑:
正如@mjwills指出的,下面是结果表insert,update和select语句。
Dapper的性能优于EF Core2。但是,可以看出,对于EF普通查询,差异非常小。我已经在这里发布了完整的详细信息。