将大型CVS文件导出到数据库c#

将大型CVS文件导出到数据库c#,c#,database,csv,C#,Database,Csv,我有一个包含1000万条目的大型CSV文件,需要使用C#将其导出到SQL。我是个新手,我真的不知道怎么写这个。 到目前为止,我有这样的想法: private static void ExportToDB() { SqlConnection con = new SqlConnection(@"Data Source=SHAWHP\SQLEXPRESS;Initial Catalog=FOO;Persist Security Info=True;User I

我有一个包含1000万条目的大型CSV文件,需要使用C#将其导出到SQL。我是个新手,我真的不知道怎么写这个。 到目前为止,我有这样的想法:

private static void ExportToDB()
        {
             SqlConnection con = new SqlConnection(@"Data Source=SHAWHP\SQLEXPRESS;Initial Catalog=FOO;Persist Security Info=True;User ID=sa");
             string filepath = @"E:\Temp.csv";
            StreamReader sr = new StreamReader(filepath);
            string line = sr.ReadLine();
            string[] value = line.Split(',');
            DataTable dt = new DataTable();
            DataRow row;
            foreach (string dc in value)
            {
                dt.Columns.Add(new DataColumn(dc));
            }

            while ( !sr.EndOfStream )
            {
                value = sr.ReadLine().Split(',');
                if(value.Length == dt.Columns.Count)
                {
                    row = dt.NewRow();
                    row.ItemArray = value;
                    dt.Rows.Add(row);
                }
            }
            SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
            bc.DestinationTableName = "tblparam_test";
            bc.BatchSize = dt.Rows.Count;
            con.Open();
            bc.WriteToServer(dt);
            bc.Close();
            con.Close();
        }
。 这给了我一个错误,说: mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常


我怎样才能修好它?或者有其他方法吗?

如果可以将文件发送到服务器。我会在服务器端使用批量插入

问候。

摘自MSDN:

与.ReadLine()相关


如果当前方法抛出OutOfMemoryException,则读取器在底层流对象中的位置将按该方法能够读取的字符数前进,但已读入内部读线缓冲区的字符将被丢弃。如果在将数据读入缓冲区后操纵基础流的位置,则基础流的位置可能与内部缓冲区的位置不匹配。要重置内部缓冲区,请调用DiscardBufferedData方法;但是,此方法会降低性能,应该仅在绝对必要时调用。

您不能使用这种方法,因为string.Split会创建大量数组,使内存量成倍增加。假设您有10列。拆分后,数组长度将为10,10字符串=11个对象。它们每个都有8或16字节的额外内存(对象同步根等)。因此,每个字符串的内存开销为88字节。10 KK行将消耗至少880 KK内存,再加上文件的这个数字大小,值将为1gb。这还不是全部,DateRow的结构相当重,因此,您应该添加10KK的数据行。这并不是全部——大小为10KK的数据表元素的大小将超过40mb。 因此,预期所需的大小超过1Gb

对于ф32 process.Net,无法轻松使用超过1Gb的内存。理论上它有2个Gig,但这只是理论上的,因为所有东西都消耗内存-程序集、本机DLL和其他对象、UI等等

解决方案是使用imk 64进程或读写块,如下所示

    private static void ExportToDB()
    {
         string filepath = @"E:\Temp.csv";
        StreamReader sr = new StreamReader(filepath);
        string line = sr.ReadLine();
        string[] value = line.Split(',');
        DataTable dt = new DataTable();
        DataRow row;
        foreach (string dc in value)
        {
            dt.Columns.Add(new DataColumn(dc));
        }

        int i = 1000; // chunk size
        while ( !sr.EndOfStream )
        {
            i--
            value = sr.ReadLine().Split(',');
            if(value.Length == dt.Columns.Count)
            {
                row = dt.NewRow();
                row.ItemArray = value;
                dt.Rows.Add(row);
            }
            if(i > 0)
               continue;
            WriteChunk(dt);                 
            i = 1000;
        }
        WriteChunk(dt);

    }
void WriteChunk(DataTable dt)
{
         SqlConnection con = new SqlConnection(@"Data Source=SHAWHP\SQLEXPRESS;Initial Catalog=FOO;Persist Security Info=True;User ID=sa");
    using(SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock))
    {
        bc.DestinationTableName = "tblparam_test";
        bc.BatchSize = dt.Rows.Count;
        using(con.Open())
        {
            bc.WriteToServer(dt);
        }
    }
    dt.Rows.Clear()
}

它可能有助于了解从何处获得此异常,以便您可以确定是文件读取还是数据库写入让您感到困惑。在这里,它尝试读取CVS:while(!sr.EndOfStream){value=sr.ReadLine().Split(','));仅仅使用如何?您是否尝试过不同的方法?没有在内存中加载所有文件,而是在插入文件时逐行解析它?我使用了您的代码,并收到了一个eror书面通知,内容如下:在建立与SQL Server的连接时发生了与网络相关或特定于实例的错误。找不到服务器或服务器已关闭无法访问。请验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。(提供程序:SQL网络接口,错误:26-查找指定的服务器/实例时出错),当我试图打开连接时,我更改了一些代码,但此错误是由您的环境引起的。是的,它无法识别第二个函数中的Sql server..在WriteChunk中…感谢您,我很快就能做到这一点!