3

我正在从 CSV 文件导入到我的 ASP.NET MVC3/C#/Entity Framework 应用程序。

目前这是我的代码,但我正在寻求优化:

var excel = new ExcelQueryFactory(file);
var data = from c in excel.Worksheet(0)
            select c;
var dataList = data.ToList();

List<FullImportExcel> importList = new List<FullImportExcel>();
foreach (var s in dataList.ToArray())
{
    if ((s[0].ToString().Trim().Length < 6) && (s[1].ToString().Trim().Length < 7))
    {
        FullImportExcel item = new FullImportExcel();
        item.Carrier = s[0].ToString().Trim();
        item.FlightNo = s[1].ToString().Trim();
        item.CodeFlag = s[2].ToString().Trim();

        //etc etc (50 more columns here)

        importList.Add(item);
    }
}

PlannerEntities context = null;
context = new PlannerEntities();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;

foreach (var item in importList)
{
    ++count;
    context = AddToFullImportContext(context, item, count, 100, true);
}

private PlannerEntities AddToFullImportContext(PlannerEntities context, FullImportExcel entity, int count, int commitCount, bool recreateContext)
{
      context.Set<FullImportExcel>().Add(entity);

      if (count % commitCount == 0)
      {
          context.SaveChanges();
          if (recreateContext)
          {
              context.Dispose();
              context = new PlannerEntities();
              context.Configuration.AutoDetectChangesEnabled = false;
          }
      }
      return context;
}

这工作得很好,但速度不够快,而且我需要做的导入每月至少有 200 万行。有没有更好的批量进口方法?我是否更好地完全避免使用 EF 并使用 SQLConnection 并以这种方式插入?

谢谢

4

3 回答 3

3

我确实喜欢您只提交每 X 条记录(在您的情况下为 100 条)的记录。

我最近编写了一个系统,每月一次,需要一次更新超过 50,000 条记录的状态 - 这是更新每条记录并为每条更新的记录插入审计记录。

本来我是用实体框架写的,做了这部分任务花了5-6分钟。SQL Profiler 向我展示了它正在执行 100,000 个 SQL 查询——每条记录一个 UPDATE 和一个 INSERT(正如我猜的那样。)

我将其更改为一个存储过程,它采用逗号分隔的记录 ID 列表、状态和用户 ID 作为参数,它执行大规模更新,然后进行大规模插入。现在需要 5 秒。

在您的情况下,对于这个数量的记录,我建议创建一个 BULK IMPORT 文件并将其传递给 SQL 以导入。

http://msdn.microsoft.com/en-us/library/ms188365.aspx

于 2012-06-14T14:06:27.767 回答
2

对于 SQL Server 中的大量插入,Bulk Copy 是最快的方法。您可以使用SqlBulkCopy类从代码中访问 Bulk Copy。您必须为您的列表创建一个 IDataReader,或者您可以使用IDataReader 插入我编写的通用列表。

于 2012-06-14T15:05:43.000 回答
0

感谢 Andy 的提醒——这是 SQL 中使用的代码,得到了帮助很大的 Pinal Dave 的一点帮助——http: //blog.sqlauthority.com/2008/02/06/sql-server-import- csv-file-into-sql-server-using-bulk-insert-load-comma-delimited-file-into-sql-server/ :)

DECLARE @bulkinsert NVARCHAR(2000)
DECLARE @filepath NVARCHAR(100)
set @filepath = 'C:\Users\Admin\Desktop\FullImport.csv'
SET @bulkinsert = 
    N'BULK INSERT FullImportExcel2s FROM ''' + 
    @filepath + 
    N''' WITH (FIRSTROW = 2, FIELDTERMINATOR = '','', ROWTERMINATOR = ''\n'')'

EXEC sp_executesql @bulkinsert

仍然需要做一些工作才能将其放入代码中,但是我们将 50000 行的时间缩短到 25 秒,而不是一个小时,这是一个巨大的改进!

于 2012-06-14T15:02:59.800 回答