Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF 6.0 SaveAll()非常慢_C#_Sql_Performance_Entity Framework - Fatal编程技术网

C# EF 6.0 SaveAll()非常慢

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

我正在使用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();
        }
    }
}

您可以尝试通过以下方式执行它。这将在执行单个操作时为您节省大量网络延迟时间

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()
也是原子的,但我可能错了)。