如何快速输入DataTable?还是将数据永久保存到DataTable中?

时间:2019-01-27 02:47:45

标签: c# sql database datatable

我正在将文本文件输入到DataTable中,然后使用SqlBulkCopy复制到数据库中。尽管BulkCopy速度很快,但不能将50000+行插入到DataTable中(大约5分钟)。如何提高效率?

我可以快速将数据插入DataTable吗? 如果没有,是否有办法将插入的数据永久保存到DataTable中,这样我就不必在每次运行程序时都将其插入?

    for (; i < fares.Length; )
            {
                k = i;
                Console.WriteLine("Inserting " + k + " out of " + (fares.Length));
                for (; i <= (k + 3); i++)
                {
                    if (i % 4 == 0)
                    {
                        for (int j = 0; j < fares.Length - 1; j++)
                        {
                            {
                                int space = fares[i].IndexOf(" ");
                                startStation = fares[i].Substring(0, space);

                                endStation = fares[i].Substring(space + 1, fares[i].Length - space - 1);

                            }
                        }
                    }

                    else if (i % 4 == 1)
                    {
                        valueFare = fares[i];
                    }
                    else if (i % 4 == 2)
                    {
                        standardFare = fares[i];

                    }
                    else if (i % 4 == 3)
                    {
                        time = int.Parse(fares[i]);
                    }


                }

                faresDT.Rows.Add(startStation, endStation, valueFare, standardFare, time);

2 个答案:

答案 0 :(得分:0)

如果您要优化数据库负载,建议您完全摆脱DataTable。通过使用Marc Gravell的FastMember(使用SqlBulkCopy的任何人都应该使用FastMember IMHO),您可以直接从任何IEnumerable获取DataReader。

每当从文件直接写入数据库时​​,我都会使用以下代码的一些变体。下面的代码将通过巧妙地使用yield return和IEnumerable的延迟加载,将文件的内容直接流式传输到SqlBulkCopy操作。

try
{
    faresDT.BeginLoadData();

    // Your for loop...
    {
        // Logic defining the value of startStation, endStation, valueFare, standardFare and time removed for briefness.
        faresDT.LoadDataRow(new object[] {startStation, endStation, valueFare, standardFare, time}, true);
    }
}
finally
{
    faresDT.EndLoadData();
}

答案 1 :(得分:-1)

在这种情况下,我认为您应该利用DataTable类中提供的BeginLoadData,LoadDataRow和EndLoadData方法,您可以像这样使用它们:

public static int convertSomeIntegerValueToSomeOtherIntegerValueByMethodOfDividingTheOriginalIntegerByTwoAndRoundingTheOutputBecauseItIsAnInteger(int veryVerboseIntegerValueWithAVeryLongParameterNameSoItCanBeDividedByTwo){
    return veryVerboseIntegerValueWithAVeryLongParameterNameSoItCanBeDividedByTwo/2;
}
public static int divTwo(int a){
    return a/2;
}

BeginLoadData()所做的是关闭每次添加一行时都会发生的某些处理,并且只有在通过调用EndLoadData()完成数据加载后才执行一次。

您可以在此处找到有关这些API的更多详细信息: https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable.loaddatarow?view=netframework-4.7.2