Cql批量复制/插入C#

时间:2013-09-17 03:47:02

标签: 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;}
}

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

6 个答案:

答案 0 :(得分:28)

由于你只需要从10到50个URL加载

,显然不需要使用SqlBulkCopy - 它适用于数千个插入。除非您需要多次重复此操作。

因此,如果您有一个网址列表,即List,那么只需遍历列表中的所有网址并将其插入数据库,例如

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);

    // don't forget to take care of connection - I omit this part for clearness
    cmd.ExecuteNonQuery();
}

但如果您确实需要使用SqlBulkCopy ,则需要将班级URL的对象转换为DataTable。为此,请查看Marc Gravell's answer

  

这是一个很好的2013年更新使用   来自NuGet的FastMember

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

是的,这几乎与this完全相反;   反思就足够了 - 或者如果你需要更快,   2.0中的HyperDescriptor,或3.5中的Expression。其实,   HyperDescriptor应该足够了。

     

例如:

// 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;        
}

因此,您可以使用Marc的某个解决方案从DataTable创建List<URL>。然后你只需要在服务器上写表到目标表:

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

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

希望它有所帮助。

UPD

  1. 回答@ pseudonym27问题:“我可以使用BulkCopy类将数据附加到SQL数据库中的现有表吗?”
  2. 当然你可以,因为BulkCopy只是插入命令,但它有点不同,就是这样。我建议你使用中间表,以防万一操作很有可能出错(你想尽可能少地占用你的目标表)或者你需要做一些数据转换,但只有你觉得需要它

答案 1 :(得分:2)

如果您使用&gt;,则应使用Table valued parameters. sql server 2005.你可以有一个例子here

答案 2 :(得分:2)

如果它只是10-50个网址,不经常插入,你可以触发插入语句。简单而轻松,你可以像简约一样轻松快捷地使用。

否则,如果您想要批量复制,则需要首先从JSON创建并填充ADO.NET数据表 - 最好匹配目标sql表的模式。这是你的选择。

答案 3 :(得分:0)

使用下面的代码,您可以将List<YourClassname>转换为DataTable:-

List<YourClass> objlist = alldata;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(objlist);
DataTable dt = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(json);
SaveDataInTables(dt, "Table_Name_Of_SQL");

在这里,我假设alldata包含list<YourClass>对象,您也可以执行-objlist.Add(objYourClass),然后在sql_TableName方法中传递SaveDataInTables和数据表。此方法会将所有数据插入SQL_Table

public void SaveDataInTables(DataTable dataTable, string tablename)
{
   if (dataTable.Rows.Count > 0)
   {
       using (SqlConnection con = new SqlConnection("Your_ConnectionString"))
       {
           using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
           {
               sqlBulkCopy.DestinationTableName = tablename;
               con.Open();
               sqlBulkCopy.WriteToServer(dataTable);
               con.Close();
            }
        }
    }
}

希望,这些代码可以为您提供帮助!

答案 4 :(得分:0)

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
   bulkCopy.DestinationTableName = "dbo.LogData";
   try
   {
      // Write from the source to the destination.
      connection.Open();
      bulkCopy.WriteToServer(dataTable1);
      connection.Close();
   }
   catch (Exception ex)
   {
      Console.WriteLine(ex.Message);
   }
}

答案 5 :(得分:-1)

我不知道您使用的数据库。但我有postgres的经验,我认为这在其他关系数据库中是相似的:

在数据库中,您也可以从csv分隔值复制(例如Postgres)。如果根据精确的输入格式格式化字符串,这应该是最快的方式。