C# EF 6.0 SaveAll()非常慢
我正在使用EF并使用此功能保存POCO对象:C# EF 6.0 SaveAll()非常慢,c#,sql,performance,entity-framework,C#,Sql,Performance,Entity Framework,我正在使用EF并使用此功能保存POCO对象: public void SaveAll(IList<CoreEntity> entitaCoreList) { bool result = false; using (var context = new NSTEntities()) { //context.Configuration.AutoDetectChangesEnabled = false; foreach (var en
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();
}
}
}
您可以尝试通过以下方式执行它。这将在执行单个操作时为您节省大量网络延迟时间
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)
}
}
}
public void SaveAll(IList<CoreEntity> entitaCoreList)
{
bool result = false;
using (var context = new NSTEntities())
{
// ... code ...
context.BulkSaveChanges();
}
}
您还可以确定发生了什么。
例如,使用如下内容:
context.Database.Log=s=>Debug.WriteLine代码>正如您所注意到的,Entity Framework SaveChanges非常慢,因为每次更改都会进行数据库往返
他们有一些您可以使用的最佳实践,比如使用AddRange而不是“Add”,但是最后,您仍然会遇到一些性能问题,因为将执行1000次数据库往返
免责声明:我是项目的所有者
显著提高性能的一种方法是使用允许使用批量操作的第三方库
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)
}
}
}
public void SaveAll(IList<CoreEntity> entitaCoreList)
{
bool result = false;
using (var context = new NSTEntities())
{
// ... code ...
context.BulkSaveChanges();
}
}
public void SaveAll(IList entitaCoreList)
{
布尔结果=假;
使用(var context=new NSTEntities())
{
//…代码。。。
context.BulkSaveChanges();
}
}
您是否在SQL Profiler中查看了它实际执行的查询?@Amy我在end@Federico如果你转向变更跟踪,你的绩效会提高吗?还要检查这个问题:EF正在做的是1000个单独的插入,以及1000个通过网络到数据库的单独往返。您的手工工具代码所做的只是一次往返:这将产生巨大的差异!EF不擅长上传大量数据。如果你需要上传大量数据,而EF的速度还不够,那么像你这样的解决方案是你必须要做的。@Simonatrc再看一次他的代码,在这之前,foreach有一个右括号。实际上还有一个额外的结束括号,所以谁知道op的意思呢?它仍然要执行1000条insert语句,但至少你保证你的保存是原子的(但我怀疑SaveChanges()
也是原子的,但我可能错了)。