Я новичок в JSON и SQLBulkCopy. У меня есть данные POST с форматированием JSON, которые я хочу скопировать / вставить в Microsoft SQL с помощью C #.
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;}
}
Как я могу сделать это эффективно?
Поскольку вам нужно загрузить только
от 10 до 50 URL-адресовочевидно, нет необходимости использовать
SqlBulkCopy
- это для тысяч вставок. За исключением случаев, когда вам понадобится повторить эту операцию много раз. Итак, если у вас есть список URL-адресов, то есть List, то просто пропустите весь URL из списка и вставьте их в базу данных, например
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
. Для этого взгляните на ответ Марка Гравелла :
Вот хорошее обновление 2013 года с использованием FastMember от NuGet:
IEnumerable<SomeType> data = ... DataTable table = new DataTable(); using(var reader = ObjectReader.Create(data)) { table.Load(reader); }
Да, это в значительной степени полная противоположность этому ; рефлексии было бы достаточно - или если вам нужно быстрее,
HyperDescriptor
в 2.0 или, может быть,Expression
в 3.5. Фактически,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 работает как команда вставки, но делает это немного по-другому, вот и все. Я бы рекомендовал использовать промежуточные таблицы в случае, если операция имеет большую вероятность ошибиться (и вы хотите заняться своей целевой таблицей как можно меньше времени), или вам нужно сделать некоторые преобразования данных, но только если вы чувствуете потребность в Это.
Используя этот код ниже, вы можете преобразовать 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();
}
}
}
}
Надеюсь, эти коды помогут вам !!!