Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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# 将数据表大容量复制到MySQL中(类似于System.Data.SqlClient.SqlBulkCopy)_C#_Mysql_Database - Fatal编程技术网

C# 将数据表大容量复制到MySQL中(类似于System.Data.SqlClient.SqlBulkCopy)

C# 将数据表大容量复制到MySQL中(类似于System.Data.SqlClient.SqlBulkCopy),c#,mysql,database,C#,Mysql,Database,我正在将我的程序从Microsoft SQL Server迁移到MySQL。除了批量复制的一个问题外,其他一切都很好 在使用MS SQL的解决方案中,代码如下所示: connection.Open(); SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); bulkCopy.DestinationTableName = "testTable"; bulkCopy.WriteToServer(rawData); 现在我尝试为MySQL做一些类似的

我正在将我的程序从Microsoft SQL Server迁移到MySQL。除了批量复制的一个问题外,其他一切都很好

在使用MS SQL的解决方案中,代码如下所示:

connection.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "testTable";
bulkCopy.WriteToServer(rawData);
现在我尝试为MySQL做一些类似的事情。因为我认为性能会很差,所以我不想将DataTable写入CSV文件,然后使用MySqlBulkLoader类进行插入

任何帮助都将不胜感激

因为我认为性能会很差,所以我不想将DataTable写入CSV文件,然后使用MySqlBulkLoader类进行插入

不要基于毫无根据的假设排除可能的解决方案。我刚刚测试了在事务中使用标准MySqlDataAdapterUpdate将System.Data.DataTable中的100000行插入MySQL表。持续运行约30秒:

使用MySqlTransaction tran=conn.BeginTransactionSystem.Data.IsolationLevel.Serializable { 使用MySqlCommand cmd=newmysqlcommand { cmd.Connection=conn; cmd.Transaction=tran; cmd.CommandText=从testtable中选择*; 使用MySqlDataAdapter da=new MySqlDataAdaptercmd { da.UpdateBatchSize=1000; 使用MySqlCommandBuilder cb=new MySqlCommandBuilderda { da.UpdaterawData; 交易承诺; } } } } 我为UpdateBatchSize尝试了几个不同的值,但它们似乎对运行时间没有显著影响

相比之下,使用MySqlBulkLoader运行以下代码只需5或6秒

字符串tempCsvFileSpec=@C:\Users\Gord\Desktop\dump.csv; 使用StreamWriter writer=newstreamwritertempcsvfilespec { Rfc4180Writer.WriteDataableRawData,writer,false; } var msbl=新的MySqlBulkLoaderconn; msbl.TableName=testtable; msbl.FileName=tempCsvFileSpec; msbl.FieldTerminator=,; msbl.FieldQuotationCharacter=''; msbl.负载; System.IO.File.DeletetempCsvFileSpec;
。。。包括使用类似的代码将100000行从DataTable转储到临时CSV文件的时间,从该文件大容量加载,然后删除该文件。

使用BulkOperation NuGet package中的任何一个,您都可以轻松完成此操作

下面是一个使用来自的包的示例

而不是使用

......
da.UpdateBatchSize = 1000;
......
da.Update(dt)
下面两行

var bulk = new BulkOperation(conn);
bulk.BulkInsert(dt);

只需5秒钟即可将整个DataTable复制到MySQL中,而无需首先将DataTable中的100000行转储到临时CSV文件中

与SqlBulkCopy类似,我们有MySqlBulkCopy for Mysql。 下面是如何使用它的示例

public async Task<bool> MySqlBulCopyAsync(DataTable dataTable)
    {
        try
        {
            bool result = true;
            using (var connection = new MySqlConnector.MySqlConnection(_connString + ";AllowLoadLocalInfile=True"))
            {
                await connection.OpenAsync();
                var bulkCopy = new MySqlBulkCopy(connection);
                bulkCopy.DestinationTableName = "yourtable";
                // the column mapping is required if you have a identity column in the table
                bulkCopy.ColumnMappings.AddRange(GetMySqlColumnMapping(dataTable));
                await bulkCopy.WriteToServerAsync(dataTable);
                return result;
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    private List<MySqlBulkCopyColumnMapping> GetMySqlColumnMapping(DataTable dataTable)
    {
        List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
        int i = 0;
        foreach (DataColumn col in dataTable.Columns)
        {
            colMappings.Add(new MySqlBulkCopyColumnMapping(i, col.ColumnName));
            i++;
        }
        return colMappings;
    }
如果表中没有任何标识列,则可以忽略列映射。 如果有标识列,则必须使用列映射,否则它将不会在表中插入任何记录 它只会给出消息,如复制了x行,但只插入了0行

这个i类可以在下面的库中找到
组件MySqlConnector,版本=1.0.0.0

可能与另一个答案重复。关于性能,您是否做过任何测试,看看将数据转储到磁盘,然后使用MySqlBulkLoader是否真的会有问题,或者实际上会比其他不使用临时文件的roll-your解决方案更糟糕?非常感谢。在您的第二次评论之后,我自己发现:-使用MySqlBulkLoader的代码对我不起作用,除非我添加msbl.LineTerminator=\r\n
public async Task<bool> MySqlBulCopyAsync(DataTable dataTable)
    {
        try
        {
            bool result = true;
            using (var connection = new MySqlConnector.MySqlConnection(_connString + ";AllowLoadLocalInfile=True"))
            {
                await connection.OpenAsync();
                var bulkCopy = new MySqlBulkCopy(connection);
                bulkCopy.DestinationTableName = "yourtable";
                // the column mapping is required if you have a identity column in the table
                bulkCopy.ColumnMappings.AddRange(GetMySqlColumnMapping(dataTable));
                await bulkCopy.WriteToServerAsync(dataTable);
                return result;
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    private List<MySqlBulkCopyColumnMapping> GetMySqlColumnMapping(DataTable dataTable)
    {
        List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
        int i = 0;
        foreach (DataColumn col in dataTable.Columns)
        {
            colMappings.Add(new MySqlBulkCopyColumnMapping(i, col.ColumnName));
            i++;
        }
        return colMappings;
    }