Entity Framwork Vs ADO .Net Vs Dapper .Net 效率比较
来源:互联网 发布:壹品曹户型优化 编辑:程序博客网 时间:2024/06/06 06:51
由我另一个博客拷贝
近年来一直使用EF+.Net MVC来编写系统,由于最近换了一个公司,碰到一个印度同事,他告诉我用Dapper比用EF高效很多,基本可以接近ADO .Net 的效率,因为习惯的问题一直没有对ORM做深入的了解的解析,所以借此机会对此三种方法进行效率测试,以便今后做大型数据处理时可以有更多的选择性。测试用例借鉴了 here。
比较版本
EF 6.2.0, Dapper 1.50.4
数据表结构
public class Sport { public Sport() { Teams = new HashSet<Team>(); } [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Name { get; set; } public ICollection<Team> Teams { get; set; } }
public class Team { public Team() { Players = new HashSet<Player>(); } [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Name { get; set; } public DateTime FoundingDate { get; set; } [ForeignKey("Sport")] public int SportId { get; set; } public Sport Sport { get; set; } public ICollection<Player> Players { get; set; } }
public class Player { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth { get; set; } [ForeignKey("Team")] public int TeamId { get; set; } public Team Team { get; set; } }
数据
Sports表加入47个不同的运动项目,大家可以网上自行搜索后加入,
Teams随即生产1000个Team,并随机分配到Sport
Players随机生成100万个Player,并随机分配到Team
数据库由EF Code First生成,并且使用比较熟悉的EF加入数据
查询Interface.
public interface ITestORM { long GetPlayerByID(int id); long GetPlayersForTeam(int teamId); long GetPlayersForSport(int sportId); }
GetPlayerByID: 根据运动员编号(主键)查找运动员
GetPlayersForTeam: 查找给定Team编号的所有运动员
GetPlayersForSport: 查找给定Sport编号的所有运动员
所以方法都不返回查找的结果,只是返回一个tick值(一千万分之一秒)
每个方法运行10次,并且取得平均值和搜寻的总时长进行比较
Entity Framework 实现代码
public class EFORM : ITestORM { private bool _tracking = true; public EFORM() { } public EFORM(bool tracking) { _tracking = tracking; } public long GetPlayerByID(int id) { Stopwatch watch = new Stopwatch(); watch.Start(); using (TestORMContext context = new TestORMContext()) { if (!_tracking) { var player = context.Players.AsNoTracking().Where(x => x.Id == id).First(); } else { var player = context.Players.Where(x => x.Id == id).First(); } } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForTeam(int teamId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (TestORMContext context = new TestORMContext()) { if (!_tracking) { var players = context.Players.AsNoTracking().Where(x => x.TeamId == teamId).ToList(); } else { var players = context.Players.Where(x => x.TeamId == teamId).ToList(); } } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForSport(int sportId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (TestORMContext context = new TestORMContext()) { if (!_tracking) { var players = context.Players.AsNoTracking().Where(player => player.Team.Sport.Id == sportId).ToList(); } else { var players = context.Players.Where(player => player.Team.Sport.Id == sportId).ToList(); } } watch.Stop(); return watch.ElapsedMilliseconds; } }
创建EF查询对象时可以用
new EFROM()
–可tracking和new EFROM(false)
–不可tracking进行查询,以便区分打开和关闭tracking时所需的查询时间,因为在上述网站上有网友提出不加tracking时,EF效率也很高效
ADO .Net 实现代码
public class ADO:ITestORM { public long GetPlayerByID(int id) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT Id, FirstName, LastName, DateOfBirth, TeamId FROM Players WHERE Id = @ID", conn)) { adapter.SelectCommand.Parameters.Add(new SqlParameter("@ID", id)); DataTable table = new DataTable(); adapter.Fill(table); } } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForTeam(int teamId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT Id, FirstName, LastName, DateOfBirth, TeamId FROM Players WHERE TeamId = @ID", conn)) { adapter.SelectCommand.Parameters.Add(new SqlParameter("@ID", teamId)); DataTable table = new DataTable(); adapter.Fill(table); } } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForSport(int sportId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT p.Id, p.FirstName, p.LastName, p.DateOfBirth, p.TeamId, t.Id as TeamId, t.Name, t.SportId FROM Players p INNER JOIN Teams t ON p.TeamId = t.Id WHERE t.SportId = @ID", conn)) { adapter.SelectCommand.Parameters.Add(new SqlParameter("@ID", sportId)); DataTable table = new DataTable(); adapter.Fill(table); } } watch.Stop(); return watch.ElapsedMilliseconds; } }
Dapper .Net 实现代码
public class DapperORM:ITestORM { public long GetPlayerByID(int id) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); var player = conn.Query<Player>("SELECT Id, FirstName, LastName, DateOfBirth, TeamId FROM Players WHERE Id = @ID", new { ID = id }); } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForTeam(int teamId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); var players = conn.Query<List<Player>>("SELECT Id, FirstName, LastName, DateOfBirth, TeamId FROM Players WHERE TeamId = @ID", new { ID = teamId }); } watch.Stop(); return watch.ElapsedMilliseconds; } public long GetPlayersForSport(int sportId) { Stopwatch watch = new Stopwatch(); watch.Start(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["TestORM"].ToString())) { conn.Open(); var players = conn.Query<Player, Team, Player>("SELECT p.Id, p.FirstName, p.LastName, p.DateOfBirth, p.TeamId, t.Id as TeamId, t.Name, t.SportId FROM Teams t " + "INNER JOIN Players p ON t.Id = p.TeamId WHERE t.SportId = @ID", (player, team) => { return player; }, splitOn: "TeamId", param: new { ID = sportId }); } watch.Stop(); return watch.ElapsedMilliseconds; } }
代码说明
上述代码基本都借鉴于 此处,不是完全拷贝,两者有部分地方有区别
测试说明
每种方法中的每个查询函数分别运行10次,每次查询的id为总记录的1/10,分别记录每个查询的时长,EF查询两次,一次tracking,一次no tracking
测试结果
说明: 运动员的编号没有从1开始,所以有下面奇怪的运动员编号 :P
EF 有 Tracking
EF 无 Tracking
ADO .Net
Dapper .Net
比较结果
感觉Dapper真的非常高效,No Tracking的EF效率也不低和ADO .Net不相上下,不过对于在系统中嵌套SQL语言,个人比较不好接受,而且不优雅,对今后维护工作也有一定麻烦,因此今后采用Dapper机会应该不多,除非一些不需要后期维护而且数据量庞大的系统或许会采用。不过仁者见仁,智者见智,当前Dapper好像非常火,但是不管用哪种方法,达到目的,而且效率不要过份低下都不失为一个好的方法。
Richard 于 2017圣诞前
- Entity Framwork Vs ADO .Net Vs Dapper .Net 效率比较
- ADO.NET - Entity Data Model vs. LINQ To SQL
- 再谈ADO .NET vs JDBC
- SSIS数据流性能比较(ADO.NET vs. OLE DB vs. ODBC)
- LINQ to SQL(LINQ2SQL) vs. ADO.NET Entity Framework(ADOEF)-ccBoy版
- 转:LINQ to SQL(LINQ2SQL) vs. ADO.NET Entity Framework(ADOEF)-ccBoy版
- LINQ to SQL(LINQ2SQL) vs. ADO.NET Entity Framework(ADOEF)-ccBoy版
- 昨日关注:C-omega vs ADO.net
- Delphi DataSet Architecture vs ADO.Net [ZZ]
- VS无ADO.NET实体数据模型?
- SSIS Data Flows - ADO.NET vs. OLE DB vs. ODBC
- vs.net 效率提升-自定义快捷键
- ADO.NET Entity Framework
- ADO.NET Entity Framework
- ADO.NET Entity Framework
- ADO.NET Entity FrameWork
- vs.net打包程序时设置自动检测环境并安装.net framwork
- vs.net打包程序时设置自动检测环境并安装.net framwork
- Android Study Material Design 十五 深入Behavior以及自定义Behavior
- python编程入门
- UITableViewCell编辑效果
- JS学习总结(一)
- 信息学奥赛一本通(C++版) 第三部分 数据结构 第三章 树
- Entity Framwork Vs ADO .Net Vs Dapper .Net 效率比较
- 关于AI,你最该了解但从没想过的四个问题
- 12.3-10周总结——设计所做包括的内容
- Laravel框架——为 WEB 艺术而生
- 16进制数据获取转换存16进制字符串
- HTML 验证
- LDD3linux设备驱动源码树的安装和第一个hello wolrd驱动的编写
- 玩转Android monkey之环境配置和ADB命令
- Python 爬虫学习笔记