我是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;}
}
我怎样才能有效地做到这一点?
答案 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
当然你可以,因为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)。如果根据精确的输入格式格式化字符串,这应该是最快的方式。