实体框架性能缓慢

问题描述:

我们使用EF 6.0,.NET 4.5和使用代码第一种方法,我们的数据库有大约170实体(表)和主表保持15万左右的记录 在实体框架的第一负荷约需25秒。 我想改善这个时间,因为这太慢了,随着记录数量的增加,它变得越来越慢。 我试图生成原生图像,尝试使用预先生成的交互式视图,但我无法实现任何重大改进。实体框架性能缓慢

任何人都可以帮助我吗?

谢谢。

+0

确保启用延迟加载 –

+0

您真的使用代码中的所有170个表吗? – ErikEJ

+0

您可以显示一个需要很长时间才能完成的示例查询吗? – Vlad274

可以考虑实体框架预产生映射视图。你可以使用EF电动工具创建预先生成视图。

使用预先生成的视图会将生成视图的代价从模型 加载(运行时间)移至编译时间。虽然这可以在运行时改善启动性能,但在开发过程中,您仍然会遇到难以生成的视图 。有几个额外的 技巧可以帮助降低视图生成的成本,编译时间和运行时间都在 。

enter image description here

您可以参考此为更多地了解它:Entity Framework Pre-Generated Mapping Views

您可以使用缓存的实体框架,以提高应用程序的性能。

缓存有3种类型。

1对象缓存 - 在ObjectStateManager建成一个ObjectContext的 情况下保持在已经 使用实例获取对象的记忆轨道。这也被称为第一级缓存,即 。

2.查询计划的缓存 - 重用当 查询被执行一次以上所生成的存储命令。

3.元数据缓存 - 通过不同的 连接到同一模型共享模型的元数据。

你可以参考这篇文章来阅读更多关于它:Performance Considerations for EF 6

+1

我试过使用预生成的意见,没有帮助。 将尝试缓存选项。 – siddhanntarora

我最近有一个运行在SSMS超快这是采取的方式,方法太长时间使用实体框架在我的C#程序运行一个简单的查询。

本页面已经被极大的帮助,在一般故障排除EF性能问题:

https://www.simple-talk.com/dotnet/net-tools/entity-framework-performance-and-what-you-can-do-about-it/

..但在这种情况下,没有任何帮助。所以,最后,我这样做:

 List<UpcPrintingProductModel> products = new List<UpcPrintingProductModel>(); 
     var sql = "select top 75 number, desc1, upccode " 
       + "from MailOrderManager..STOCK s " 
       + "where s.number like @puid + '%' " 
     ; 
     var connstring = ConfigurationManager.ConnectionStrings["MailOrderManagerContext"].ToString(); 
     using (var connection = new SqlConnection(connstring)) 
     using (var command = new SqlCommand(sql, connection)) { 
      connection.Open(); 
      command.Parameters.AddWithValue("@puid", productNumber); 
      using (SqlDataReader reader = command.ExecuteReader()) { 
       while (reader.Read()) { 
        var product = new UpcPrintingProductModel() { 
         ProductNumber = Convert.ToString(reader["number"]), 
         Description = Convert.ToString(reader["desc1"]), 
         Upc = Convert.ToString(reader["upccode"]) 
        }; 
        products.Add(product); 
       } 
      } 
     } 

(对于这个特定的查询,我只是完全完全绕过了EF,以及所使用的旧的备用:System.Data.SqlClient的)

你会起皱厌恶你的鼻子;我当然这么做了 - 但实际上这并没有花很长时间来写,而且几乎立即执行。

+1

“皱我的鼻子”?这是超级聪明的。 +1使用EF作为主流,在有意义的情况下使用EF作为例外。这是一个重要的配置示例。 – Rap

您也可以在应用程序启动时异步“加热”您的dbcontexts以避开此问题。

protected void Application_Start() 
{ 
    // your code. 
    // Warming up. 
      Start(() => 
      { 
       using (var dbContext = new SomeDbContext()) 
       { 
        // Any request to db in current dbContext. 
        var response1 = dbContext.Addresses.Count(); 
       } 
      }); 
} 

private void Start(Action a) 
{ 
    a.BeginInvoke(null, null); 
} 

我还建议使用这样的设置为:(是否符合您的应用程序)

  • dbContext.Configuration.AutoDetectChangesEnabled = FALSE; dbContext.Configuration.LazyLoadingEnabled = false; dbContext.Configuration.ProxyCreationEnabled = false;

  • 跳过验证部分(即Database.SetInitializer<SomeDbContext>(null);

  • 对GET查询使用.asNoTraking()

有关更多信息,你可以阅读: