繁体   English   中英

C#读取大型Excel XLSX并将数据写入到SQL Server Express数据库时出现实体框架性能问题

[英]C# reading large excel xlsx and writing data to sql server express database with entity framework performance issues

我有一个非常大的xlsx文件(6张纸,每张纸100万行,每张19列)。 这个想法是读取所有工作表中的所有行,并使用实体框架填充数据库。

我已经尝试过ms open xml sdk,但是它真的很慢。 只是为了遍历所有行和单元格(以sax方式),我可能会将程序运行一个月或更长时间。

我也尝试过该库https://github.com/ExcelDataReader/ExcelDataReader 最初,使用该库的读取开始速度更快(使用db插入,在2秒钟内大约有100行),但实际上却变慢了(在50000行,1分钟或更长时间之后)。 也许速度降低会导致实体框架-我没有测试(我只测试了可能没有数据库访问的前1000行),但是即使是这样,没有任何内容的读取也太慢了。

有谁知道如何加快xlsx的阅读速度? 另外,我是否应该放弃实体框架并自行插入?

目前,我的代码看起来像(有一些诸如columnMapper.Populate(tmpColumns, columns);columnMapper.getCOlumnId类的东西columnMapper.Populate(tmpColumns, columns);因为不同的工作表具有不同的列顺序甚至是不同的列数)

using (FileStream stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read))
{
    IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
    DataSet result = excelReader.AsDataSet();

    int tableNo = 0;
    string[] tmpColumns = new string[20];
    Console.WriteLine("Start processing...");
    foreach (DataTable table in result.Tables)
    {
        // skip bad table
        if (++tableNo > 5)
        {
            continue;
        }

        for (int i = 0; i < tmpColumns.Length; ++i)
        {
            tmpColumns[i] = string.Empty;
        }

        int columns = 0;
        var rowEnumerator = table.Rows.GetEnumerator();
        rowEnumerator.MoveNext();
        foreach (string item in ((DataRow)rowEnumerator.Current).ItemArray)
        {
            tmpColumns[columns++] = item;
        }

        columnMapper.Populate(tmpColumns, columns);

        int rowNumber = 0;
        while (rowEnumerator.MoveNext())
        {
            var row = (DataRow)rowEnumerator.Current;
            int col = 0;
            foreach (object item in row.ItemArray)
            {
                tmpColumns[columnMapper.GetColumnId(col++)] = item.ToString();
            }


            var newBoxData = new BoxData()
            {
...
                Year = tmpColumns[4],
                RetentionPeriod = tmpColumns[6],
                ContractNumber = tmpColumns[7],
                Mbr = tmpColumns[8],
                CardId = tmpColumns[10],
                Package = tmpColumns[12],
                UnitType = tmpColumns[13],

                MFCBox = tmpColumns[14],
                DescriptionNameAndSurname = tmpColumns[15],
                DateFromTo = tmpColumns[16],
                OrderNumberRange = tmpColumns[17],
                PartnerCode = tmpColumns[18],
            };

            db.BoxesDatas.Add(newBoxData);

            if (++rowNumber % SaveAfterCount == 0)
            {
                db.SaveChanges();
                Console.WriteLine(rowNumber);
            }
        }
    }

    db.SaveChanges();

编辑:解决方案是删除实体fw并使用普通sql命令插入数据。 因此,在离开ms库(实体fw,打开xml sdk)并用ExcelDataReader替换它们之后,普通sql插入将使一切运行得更快。 提取约2,000,000行并将其插入db少于20分钟

解决XL性能问题后,您还将遇到EF性能问题。
第一步是有时创建一个新的DbContext(即在SaveChanges之后)。
第二步是使用不同的ORM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM