Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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# 使用实体框架将大量行插入数据库_C#_Entity Framework_Localdb - Fatal编程技术网

C# 使用实体框架将大量行插入数据库

C# 使用实体框架将大量行插入数据库,c#,entity-framework,localdb,C#,Entity Framework,Localdb,@EDIT 我遵循了中的步骤,得到了更糟糕的结果,因此它不是重复的。 我的目标是创建一个seed方法来填充LocalDb的一个表。该方法将添加182500行(模拟500台设备的年度活动数据),以进行进一步测试。我可能想再运行几次来更改设备的数量,这样会生成更多的行。这就是为什么我需要尽可能高效地插入行 protected void SeedReportDataTable(int numberOfTerminals) { var rand = new Random(

@EDIT 我遵循了中的步骤,得到了更糟糕的结果,因此它不是重复的。

我的目标是创建一个seed方法来填充LocalDb的一个表。该方法将添加182500行(模拟500台设备的年度活动数据),以进行进一步测试。我可能想再运行几次来更改设备的数量,这样会生成更多的行。这就是为什么我需要尽可能高效地插入行

    protected void SeedReportDataTable(int numberOfTerminals)
    {
        var rand = new Random();
        var tidsList = new List<string>();

        // generuj liste losowych numerow tid
        for (int i = 0; i < numberOfTerminals; i++)
        {
            var randomTid = rand.Next(100000, 1000000).ToString(); // generuj 6-cyfrowy numer tid
            while (tidsList.Contains(randomTid)) { randomTid = rand.Next(100000, 1000000).ToString(); } // elminuj powtorzenia
            tidsList.Add(randomTid);
        }

        // dla kazdego z numerow tid generuj roczna historie aktywnosci
        var recordsList = new BlockingCollection<ReportData>();
        int year = Convert.ToInt32(DateTime.Now.Year);

        Parallel.ForEach(tidsList, tid =>
        {
            // dla kazdego miesiaca
            for (int month = 1; month <= 12; month++)
            {
                // dla kazdego dnia
                for (int day = 1; day <= DateTime.DaysInMonth(year, month); day++)
                {
                    var record = new ReportData
                    {
                        Tid = tid,
                        Active = Convert.ToBoolean(
                            rand.Next(0, 11)), // generuj losowy stan aktywnosci z prawdopodbienstwem 1/10 na bycie nieaktywnym
                        Date = new DateTime(year, month, day)
                    };
                    recordsList.Add(record);
                }
            }
        });
        // dodaj unikalne klucze glowne rekordom przed dodaniem do kontekstu bazy
        var keyValue = 1;

        foreach (var record in recordsList)
        {
            record.Id = keyValue++;
        }

        // podziel liste na czesci
        int chunkSize = 1000;

        for (int recordsSkipped = 0; recordsSkipped < recordsList.Count; recordsSkipped += chunkSize)
        {
            // wymieniaj kontekst
            using (var db = new dbEntities())
            {
                db.Configuration.AutoDetectChangesEnabled = false;
                db.Configuration.ValidateOnSaveEnabled = false;
                // dodawaj do bazy po kawalku
                db.ReportData.AddRange(recordsList.Skip(recordsSkipped).Take(chunkSize));
                db.SaveChanges();
            }
        }
    }
这花了15分钟,仍然比我预期的慢

为什么我的“改进”失败了


如何使其更快地插入行?

当我将种子设定方法添加到
Configuration.cs
并运行
updatedatabase
命令时,插入所有行所需的时间不到5分钟

当只调用一次
Context.AddRange()
时效果最好

        dbContext.Configuration.AutoDetectChangesEnabled = false;
        dbContext.Configuration.ValidateOnSaveEnabled = false;
        dbContext.ReportData.AddRange(recordsList);
        dbContext.SaveChanges();

如果使用EF在一个数据库中植入那么多记录,那么可能会重复上述情况,这并不是最有效的选择。如果在插入大量记录(数百万或更多)时,性能是最重要的,请考虑使用SQL批量插入。即使这样,您也应该检查Sql Server是否存在瓶颈(即,跨插入的索引更新和统计信息更新也会降低此类批处理作业的速度)。
它不是重复的,因为我遵循了该主题中的提示,得到了更差的结果
您可以向我们展示您使用
SqlBulkCopy
测试的代码版本吗(并与我们分享执行所需的时间)?据我所知,BlockingCollection没有随机访问,因此重复的
recordsList.Skip(…).Take(…)
在循环中,跳过的元素越多,占用的时间就越长。您需要使用不同的数据结构来跳过/take,或者使用不同的分块方法。
我必须将列表转换为datatable。
        dbContext.Configuration.AutoDetectChangesEnabled = false;
        dbContext.Configuration.ValidateOnSaveEnabled = false;
        dbContext.ReportData.AddRange(recordsList);
        dbContext.SaveChanges();