我正在使用EF并使用此功能保存我的POCO对象:
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();
}
}
}
但它非常慢,1000条记录需要近25秒。 我尝试使用这样的原始查询:
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)',@0=@p3,@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'
答案 0 :(得分: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 :(得分:0)
正如您所注意到的,实体框架SaveChanges非常慢,因为每次更改都会进行数据库往返。
他们有一些您可以使用的最佳做法,例如使用 AddRange 而不是“添加”,但最后,您仍会遇到一些性能问题,因为将执行1000次数据库往返。
免责声明:我是该项目的所有者Entity Framework Extensions
显着提高性能的一种方法是使用允许使用批量操作的第三方库。
public void SaveAll(IList<CoreEntity> entitaCoreList)
{
bool result = false;
using (var context = new NSTEntities())
{
// ... code ...
context.BulkSaveChanges();
}
}