我是使用 ORM 处理数据库的新手,目前我正在制作一个新项目,我必须决定是使用 Entity Framework 还是 Dapper。我读过很多文章,都说 Dapper 比实体框架更快。
因此,我制作了 2 个简单的原型项目,一个使用 Dapper,另一个使用实体框架和一个函数来从一张表中获取所有行。
表架构如下图
两个项目的代码如下
对于 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());
对于实体框架项目
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
在多次尝试上述代码后,仅在第一次运行该项目时,简洁的代码会更快,并且在第一次之后,我总是从实体框架项目中获得更好的结果
我还在实体框架项目上尝试了以下语句来停止延迟加载
hrctx.Configuration.LazyLoadingEnabled = false;
但除了第一次之外,相同的 EF 仍然执行得更快。
尽管网络上的所有文章都说相反的内容,但任何人都可以给我解释或指导如何使 EF 在此示例中更快
Update
我已将实体示例中的代码行更改为
IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();
使用不追踪正如一些文章中提到的,停止实体框架缓存,停止缓存后,dapper 示例的性能更好,(但差别不是很大)
ORM(对象关系映射器)是一种在应用程序和数据源之间创建层并返回关系对象而不是对象的工具。
(就您正在使用的 C# 而言)ADO.NET 对象。这是每个 ORM 所做的基本事情。
为此,ORM 通常会执行查询并map返回的DataReader
到 POCO 类。 Dapper 仅限于此。
为了进一步扩展这一点,一些 ORM(也称为“完整 ORM”)可以做更多的事情,例如为您生成查询以使您的应用程序数据库独立、缓存您的数据以供将来调用、为您管理工作单元等等。所有这些都是很好的工具,为 ORM 增加了价值;但这是有代价的。实体框架属于此类。
为了生成查询,EF 必须执行额外的代码。缓存提高了性能,但管理缓存需要执行额外的代码。对于工作单元和 EF 提供的任何其他附加功能也是如此。这一切都节省了you编写额外的代码,EF 支付成本。
And the cost是性能。由于 Dapper 做了非常基本的工作,所以速度更快;但你必须编写更多代码。由于 EF 的作用远不止于此,因此它(有点)慢;但你必须编写更少的代码。
那么为什么你的测试显示相反的结果呢?
因为您正在执行的测试不具有可比性。
如上所述,完整的 ORM 有许多好的特性;其中之一是UnitOfWork。跟踪是 UoW 的职责之一。当第一次请求该对象(SQL 查询)时,会导致与数据库的往返。然后该对象被保存在内存缓存中。完整的 ORM 会跟踪对此已加载的对象所做的更改。如果再次请求相同的对象(同一 UoW 范围内包含已加载对象的其他 SQL 查询),它们不会进行数据库往返。相反,它们从内存缓存中返回对象。这样,可以节省大量时间。
Dapper 不支持此功能,这会导致它在测试中执行速度变慢。
但是,此优点仅适用于多次加载相同对象的情况。此外,如果内存中加载的对象数量太多,这会减慢整个 ORM 的速度,因为check内存中的对象会更高。同样,这种好处取决于用例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)