最近在网上看到一篇帖子,介绍说在大量数据库操作时EF的性能甚至超过ADO.NET。个人感觉疑惑,作为O/RM框架,而且下层使用ADO.NET操作数据库为什么在性能上还能够超过ADO.NET呢?于是我做了个简单的测试,测试结果如下:重复50次操作:
使用EF操作:(单位:ms,循环3次)Add:795 Query:519 update:600 delete:230Add:225 Query 350  update:575 delete:225Add:225 Query:250 update 760 delete:250使用ADO.NET:Add:165 Query:155 update:160 delete:155Add:165 Query:160 update:155 delete:160Add:165 Query:165 update:155 delete:155
重复5000次操作EF:Add:23524 Query:35611 update:58852 delete:23100Add:23882 Query:35690 update:57898 delete:23065Add:23827 Query:35845 update:59306 delete:23217ADO.Net:Add:17045 Query:15937 update:16207 delete:16197Add:17460 Query:15952 update:15665 delete:15955Add:17277 Query:18183 update:15935 delete:16890单单从测试的角度来看视乎EF的性能和ADO.NET差了一大接,而且我同时也做了LinqToSQL的测试。感觉EF的性能和LinqToSQL差不多。为什么测试结果和网上的描述相差会这么大? 由于个人能力缘故可能问题出在我自己的代码上,所以我将测试源代码公布如下,希望高手们能帮我看看。Entity Framework: for (var i = 0; i < 50; i++)     {      using (var ctx = new Test.EF.sq_sinospacedbEntities())      {       var item = new Test.EF.testtable()       {        content = "啊啊啊啊啊啊啊啊啊啊啊",        summary = "啊飒飒飒飒",        m_id = 1,        title = "啊飒飒飒",        id = i       };       ctx.testtable.AddObject(item);       ctx.SaveChanges();      }     }     var _add = DateTime.Now;     Console.Write(String.Format(" Add:{0}", _add.Subtract(add).Minutes * 60 * 1000 + _add.Subtract(add).Seconds * 1000 + _add.Subtract(add).Milliseconds)); for (var i = 0; i < 50; i++)     {      using (var ctx = new Test.EF.sq_sinospacedbEntities())      {       var items = ctx.testtable        .FirstOrDefault(c => c.id == i);      }     }     var _query = DateTime.Now;     Console.Write(String.Format(" Query:{0}", _query.Subtract(query).Minutes * 60 * 1000 + _query.Subtract(query).Seconds * 1000 + _query.Subtract(query).Milliseconds));     update = DateTime.Now;     for (var i = 0; i < 50; i++)     {      using (var ctx = new Test.EF.sq_sinospacedbEntities())      {       ctx.testtable.Single(c => c.id == i).title = "巴巴变版本";       ctx.SaveChanges();      }     }     var _update = DateTime.Now;     Console.Write(String.Format(" update:{0}", _update.Subtract(update).Minutes * 60 * 1000 + _update.Subtract(update).Seconds * 1000 + _update.Subtract(update).Milliseconds)); delete = DateTime.Now;     for (var i = 0; i < exenum; i++)     {      var deleteitem = new Test.EF.testtable()      {       id = i      };      using (var ctx = new Test.EF.sq_sinospacedbEntities())      {       ctx.testtable.Attach(deleteitem);       ctx.ObjectStateManager.ChangeObjectState(deleteitem,         System.Data.EntityState.Deleted);       ctx.SaveChanges();      }     }     var _delete = DateTime.Now;     Console.Write(String.Format(" delete:{0}", _delete.Subtract(delete).Minutes * 60 * 1000 + _delete.Subtract(delete).Seconds * 1000 + _delete.Subtract(delete).Milliseconds));ADO.NET:add = DateTime.Now;     for (var i = 0; i < 5000; i++)     {      using (var con = new SqlConnection("Data Source=.;Initial Catalog=sq_sinospacedb;Persist Security Info=True;User ID=hugo;Password=MYvalentinE;"))      {       SqlCommand com = new System.Data.SqlClient.SqlCommand(        "insert into testtable values('" + i + "','啊飒飒飒','啊飒飒飒飒','啊啊啊啊啊啊啊啊啊啊啊',1)", con);       con.Open();       com.ExecuteNonQuery();       con.Close();      }  var _add = DateTime.Now;     Console.Write(String.Format(" Add:{0}", _add.Subtract(add).Minutes * 60 * 1000 + _add.Subtract(add).Seconds * 1000 + _add.Subtract(add).Milliseconds));     query = DateTime.Now;     for (var i = 0; i < 5000; i++)     {      using (var con = new SqlConnection("Data Source=.;Initial Catalog=sq_sinospacedb;Persist Security Info=True;User ID=hugo;Password=MYvalentinE;"))      {       SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(        "select * from testtable where id=" + i, con);       DataSet ds = new DataSet();       con.Open();       da.Fill(ds);      } var _query = DateTime.Now;     Console.Write(String.Format(" Query:{0}", _query.Subtract(query).Minutes * 60 * 1000 + _query.Subtract(query).Seconds * 1000 + _query.Subtract(query).Milliseconds));     update = DateTime.Now;     for (var i = 0; i < 5000; i++)     {      using (var con = new SqlConnection("Data Source=.;Initial Catalog=sq_sinospacedb;Persist Security Info=True;User ID=hugo;Password=MYvalentinE;"))      {       SqlCommand com = new System.Data.SqlClient.SqlCommand(        "update testtable set title='巴巴变版本' where id=" + i, con);       con.Open();       com.ExecuteNonQuery();       con.Close();      }   delete = DateTime.Now;     for (var i = 0; i < 5000; i++)     {      using (var con = new SqlConnection("Data Source=.;Initial Catalog=sq_sinospacedb;Persist Security Info=True;User ID=hugo;Password=MYvalentinE;"))      {       SqlCommand com = new System.Data.SqlClient.SqlCommand(        "delete testtable where id=" + i, con);       con.Open();       com.ExecuteNonQuery();       con.Close();      }     }     var _delete = DateTime.Now;     Console.Write(String.Format(" delete:{0}", _delete.Subtract(delete).Minutes * 60 * 1000 + _delete.Subtract(delete).Seconds * 1000 + _delete.Subtract(delete).Milliseconds));

解决方案 »

  1.   

    LINQ to SQL 允许你用任何类来代表数据库中的数据、表。同样的,EF也允许你用任何类来代表苏据库中的数据、表。所不同的的地方是Linq to sql 用这些被修饰过的类直接同数据库打交道,存取数据。但是EF的类则必须通过一个中间层(叫Entity Data Model, EDM)来和数据库打交道,存取数据。
    这就造成了Entity Framework无论如何不可能比Linq to SQL 快,尽管它很可能在灵活性上会比Linq to sql 要强
      

  2.   

    在循环内执行       using (var ctx = new Test.EF.sq_sinospacedbEntities())   ?你在实际软件中真的会这样编码?那么先学编码。
      

  3.   

    2楼 可能没懂我的意思。我是在测试EF的性能,因为所有用户应该都是先初始化ctx。然后写具体的操作吧。我这样做只是为了模拟有N个人在操作EF。因为所有的人要使用EF都会先初始化ctx
      

  4.   

    我想知道有人有真正测试过EF Linq-To-SQL ADO.NET他们之间的访问性能吗?网上所谓的EF性能在大量操作中性能超越ADO.NET是不是只是谣言