2016-02-29 16 views
0

我使用EF和使用該功能救了我的POCO對象:EF 6.0白水回收()很慢

public void SaveAll(IList<CoreEntity> entitaCoreList) 
{ 
    bool result = false; 

    using (var context = new NSTEntities()) 
    { 
     //context.Configuration.AutoDetectChangesEnabled = false; 
     foreach (var entitaCore in entitaCoreList) 
     { 
      TRACCIAVEICOLO_T500 tracciamentoVeicoliEF = new TRACCIAVEICOLO_T500(); 
          tracciamentoVeicoliEF.C_IDTRACCIAMENTOVEICOLO = tracciaVeicolo.Id; 
     CultureInfo ci = CultureInfo.CreateSpecificCulture("en-EN"); 
     tracciamentoVeicoliEF.Z_COORD = System.Data.Spatial.DbGeography.PointFromText(
      "POINT (" + tracciaVeicolo.Longitudine.ToString(ci) + " " + tracciaVeicolo.Latitudine.ToString(ci) + ")", 4326); 
     tracciamentoVeicoliEF.D_DATARILEVAZIONE = tracciaVeicolo.DataRilevazione; 
     tracciamentoVeicoliEF.C_CODICEWEBFLEET = tracciaVeicolo.CodiceVeicoloWebfleet; 
     tracciamentoVeicoliEF.S_POSITIONSTRING = tracciaVeicolo.posString; 
     tracciamentoVeicoliEF.P_TIPOMESSAGGIO = (int) tracciaVeicolo.TipoMessaggio; 
     tracciamentoVeicoliEF.V_VELOCITA = tracciaVeicolo.Velocita; 
     tracciamentoVeicoliEF.V_DIREZIONE = tracciaVeicolo.Direzione; 
     tracciamentoVeicoliEF.S_GPSSTATUS = tracciaVeicolo.GpsStatus; 
     tableSet.Add(tracciamentoVeicoliEF); 
     } 

     context.SaveChanges(); 
     } 
    } 
} 

但它是非常緩慢的,它需要近25秒1000條記錄。 我嘗試使用原始的查詢是這樣的:

 public void SaveRaw(List<TracciaVeicolo> v) 
     { 
      StringBuilder query = new StringBuilder(); 
query.Append(@"INSERT INTO [dbo].[TRACCIAMENTOVEICOLI_T500]([Z_COORD],[C_CODICEWEBFLEET],[D_DATARILEVAZIONE],[S_POSITIONSTRING],[P_TIPOMESSAGGIO],[V_VELOCITA],[V_DIREZIONE],[S_GPSSTATUS])VALUES "); 
      bool first = true; 
      foreach(var o in v) 
      { 
       if (!first) 
       { 
        query.Append(","); 
       } 
       query.AppendFormat("(geography::Point(47.65100, -122.34900, 4326),'{0}','{1}','{2}',{3},{4},{5},'{6}')" 
        , o.CodiceVeicoloWebfleet 
        ,o.DataRilevazione.ToString("yyyy-dd-MM HH:mm:ss") 
       ,o.posString 
       , (int)o.TipoMessaggio 
       , o.Velocita 
       , o.Direzione 
       , o.GpsStatus); 
       first = false; 
      } 

      using (var context = new NSTEntities()) 
      { 
       context.Database.ExecuteSqlCommand(query.ToString()); 
      } 
     } 

它需要5秒鐘。我使用EF錯誤嗎?我已經使用context.Configuration.AutoDetectChangesEnabled = false;(你可以在第一個代碼段見)也嘗試過,但它不會改變任何東西

查詢EF運行是這樣的:

declare @p3 sys.geography 
set @p3=convert(sys.geography,0xE6100000010CE9297288B82F44404DF4F92823263240) 
exec sp_executesql N'insert [dbo].[TRACCIAMENTOVEICOLI_T500]([Z_COORD], [C_CODICEWEBFLEET], [D_DATARILEVAZIONE], [S_POSITIONSTRING], [P_TIPOMESSAGGIO], [V_VELOCITA], [V_DIREZIONE], [S_GPSSTATUS]) 
values (@0, @1, @2, @3, @4, @5, @6, @7) 
select [C_IDTRACCIAMENTOVEICOLO] 
from [dbo].[TRACCIAMENTOVEICOLI_T500] 
where @@ROWCOUNT > 0 and [C_IDTRACCIAMENTOVEICOLO] = scope_identity()',N'@0 [geography],@1 nvarchar(20),@2 datetime2(7),@3 nvarchar(256),@4 int,@5 float,@6 int,@7 char(1)',@[email protected],@1=N'1-83645-666EE1173',@2='2016-02-29 15:34:57',@3=N'Vicino a Lecce, 1a Lecce Centro-1B ',@4=0,@5=8,3333333333333339,@6=50,@7='A' 
+1

您是否在SQL Profiler中查看過其實際正在執行的查詢? – Amy

+0

@Amy我在末尾添加了EF查詢 – Federico

+0

@Federico如果您開始更改跟蹤,是否會提高性能? http://stackoverflow.com/questions/21272763/entity-framework-performance-issue-savechanges-is-very-slow另外檢查這個問題:http://stackoverflow.com/questions/5940225/fastest-way-of-插入實體框架 – user1666620

回答

0

您可以嘗試執行它通過combining several operations into one transaction。當您執行單個操作時,這會爲您節省大量時間,導致網絡延遲。

using (var context = new NSTEntities()) 
{ 
    using (var dbContextTransaction = context.Database.BeginTransaction()) 
    { 
     try 
     { 
      [... foreach ... tableSet.Add(...) ...] 

      context.SaveChanges(); 

      dbContextTransaction.Commit(); 
     } 
     catch (Exception exception) 
     { 
      dbContextTransaction.Rollback(); 
      // Log exception (never ignore) 
     } 
    } 
} 

您也可以通過log the SQL-operations來確定發生了什麼。 例如使用類似的東西:context.Database.Log = s => Debug.WriteLine(s);

+1

它仍然會做1000個插入語句,但至少你保證你的保存是原子的(但我懷疑'SaveChanges()'也是原子的,但我可能是錯的)。 –

0

正如您所注意到的,實體框架SaveChanges是非常緩慢的,因爲每次更改都會進行數據庫往返。

他們有一些最佳實踐,你可以使用像使用AddRange而不是「添加」,但最終,你仍然會有一些性能問題,因爲將執行1000次數據庫往返。

免責聲明:我是這個項目的所有者Entity Framework Extensions

一來大大提高性能的方法是使用第三方庫,它允許使用批量操作。

public void SaveAll(IList<CoreEntity> entitaCoreList) 
{ 
    bool result = false; 

    using (var context = new NSTEntities()) 
    { 
     // ... code ... 

     context.BulkSaveChanges(); 
    } 
}