c# - C# 中的 SQL 批量复制/插入

标签 c# .net sql sqlbulkcopy

我是 JSON 和 SQLBulkCopy 的新手。我有一个 JSON 格式的 POST 数据,我想使用 C# 在 Microsoft SQL 中批量复制/插入这些数据。

JSON 格式:

{
    "URLs": [{
        "url_name": "Google",
        "url_address": "http://www.google.com/"
    },
    {
        "url_name": "Yahoo",
        "url_address": "http://www.yahoo.com/"
    },
    {
        "url_name": "FB",
        "url_address": "http://www.fb.com/"
    },
    {
        "url_name": "MegaSearches",
        "url_address": "http://www.megasearches.com/"
    }]
}

类:

public class UrlData
{
    public List<Url> URLs {get;set;}
}

public class Url
{
    public string url_address {get;set;}
    public string url_name {get;set;}
}

我怎样才能有效地做到这一点?

最佳答案

TL;DR 如果您的数据已经表示为 DataTable,您可以使用 SqlBulkCopy 将其插入到服务器上的目标表中:

string csDestination = "put here the a connection string to the database";

using (SqlConnection connection = new SqlConnection(csDestination))
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
    connection.Open()
    bulkCopy.DestinationTableName = "TUrls";
    bulkCopy.WriteToServer(dataTableOfUrls);
}

如果您只想加载“从 10 到 50 个 url”,则无需使用 SqlBulkCopy - 它的一般用途是消除数千个单独的插入。

因此,插入没有 SqlBulkCopy [并且没有EntityFramework]可以一一完成:

string insertQuery = "insert into TUrls(address, name) values(@address, @name)";
foreach (URL url in listOfUrls)
{
    SqlCommand cmd = new SqlCommand(insertQuery);
    cmd.Parameters.AddWithValue("@name", url.url_name);
    cmd.Parameters.AddWithValue("@address", url.urld_address);

    // Remember to take care of connection! I omit this part for clarity
    cmd.ExecuteNonQuery();
}

要使用 SqlBulkCopy 插入数据,您需要将数据(例如自定义类对象列表)转换为 DataTable。以下是来自 Marc Gravell's answer 的引述作为此类转换的通用解决方案示例:

Here's a nice 2013 update using FastMember from NuGet:

IEnumerable<SomeType> data = ...
DataTable table = new DataTable();
using(var reader = ObjectReader.Create(data)) {
    table.Load(reader);
}

Yes, this is pretty much the exact opposite of this one; reflection would suffice - or if you need quicker, HyperDescriptor in 2.0, or maybe Expression in 3.5. Actually, HyperDescriptor should be more than adequate.

For example:

// remove "this" if not on C# 3.0 / .NET 3.5
public static DataTable ToDataTable<T>(this IList<T> data)
{
    PropertyDescriptorCollection props =
        TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for(int i = 0 ; i < props.Count ; i++)
    {
        PropertyDescriptor prop = props[i];
        table.Columns.Add(prop.Name, prop.PropertyType);
    }
    object[] values = new object[props.Count];
    foreach (T item in data)
    {
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = props[i].GetValue(item);
        }
        table.Rows.Add(values);
    }
    return table;        
}

现在,将您的数据表示为 DataTable,您已准备好将其写入服务器上的目标表:

string csDestination = "put here the a connection string to the database";

using (SqlConnection connection = new SqlConnection(csDestination))
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
    connection.Open();
    bulkCopy.DestinationTableName = "TUrls";
    bulkCopy.WriteToServer(dataTableOfUrls);
}

希望对您有所帮助。

**更新:**

  1. @pseudonym27 问题的答案:“你好,我可以使用 BulkCopy 类将数据附加到 SQL 数据库中的现有表吗?”

是的,您可以 - BulkCopy 以附加数据的方式作为插入命令工作。
此外,考虑使用中间表以防操作出错的可能性很高(例如,插入时间长和连接问题),并且您希望尽可能少地忙于/锁定目标表。当然,中间表的另一个用例是需要在插入之前进行一些数据转换。

关于c# - C# 中的 SQL 批量复制/插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18841000/

相关文章:

c# - 如何将 C# SSLStream 客户端连接到 OpenSSL 服务器?

c# - ReSharper 警告 - 访问修改后的闭包

c# - 如何合并两个 lambda

.net - 如何使用 WCF 的 ChannelFactory<T> 实现客户端异步调用?

c# - ListView Observable 集合不会显示成员

c# - 值列表中的值存在于弹性字段列表嵌套C#中

C# 修改 parallel.foreach 中的 DataRow 数组引用,为什么代码运行正确?

php - 如何比较逗号分隔值和两个不同的ids-php mysql

php - 包含所有 where 情况以进行一个 sql 查询

mysql - 关于创建临时列的 SQL