ahmed_sa Ответов: 1

Как создать инструкцию function return insert в табличные значения из json-файла ?


Проблема

Как вернуть оператор insert в табличные значения из json-файла ?

Я работаю над библиотекой newton soft и пытаюсь вставить данные в таблицу master_table

но моя проблема как сделать функцию return insert statement как показано ниже :

вставить в master_table(id,branch_id,имя,адрес,телефон) значения (1,1,"бар","Флит-стрит","555")

содержание таблицы ,ключей,полей гибкое или динамическое .

мой jsonfile D:\\1.json как показано ниже :

{
   "master" : {
       "table": "master_table",
       "fields": {
           "name" : "bar",
           "address" : "fleet street",
           "phone" : "555"
       },
       "keys":{
           "id" : 1,
           "branch_id" : 1 
       }
       
   }
}



Я уже делаю get ключи и поля, но не могу сделать конкатенацию
инструкция как результат .

Как объединить оператор insert с ключами + полями
как заявление на первом потоке .


Что я уже пробовал:

public static ExpandoObject ToExpando(string json)  {  
  if (string.IsNullOrEmpty(json))  
    return null;  
  
  return (ExpandoObject)ToExpandoObject(JToken.Parse(json));  
}  
  
  
private static object ToExpandoObject(JToken token)  
{  
  
switch (token.Type) {  
  case JTokenType.Object:  
    var expando = new ExpandoObject();  
    var expandoDic = (IDictionary<string, object>)expando;  
    
    foreach (var prop in token.Children<JProperty>())  
        expandoDic.Add(prop.Name, ToExpandoObject(prop.Value));  
        return expando;  
  case JTokenType.Array:  
        return token.Select(ToExpandoObject).ToList();  
  
  default:  
        return ((JValue)token).Value;  
  }  
} 

static void Main(string[] args)  {  
  string JsonData = File.ReadAllText("D:\\1.json");  
  var ebj = SqlFactory.ToExpando (JsonData);  
  var name = (ebj as dynamic).master.table;  
  var fields = (ebj as dynamic).master.fields;  
  
  foreach (dynamic i in fields)  {  
    string key = i.Key;  
    object value = i.Value;  
  }  
  
  var keys = (ebj as dynamic).master.keys;  
}

1 Ответов

Рейтинг:
1

Maciej Los

Кажется, вы используете Json.NET[^] библиотека...

Итак, вы должны сделать что-то вроде этого:

JObject jo = JObject.Parse(json);
JToken m = jo["master"];

StringBuilder sb = new StringBuilder();
string s = string.Format("INSERT INTO {0} ", m["table"]);
sb.Append(s);
sb.Append("(");
foreach(JProperty jp in m["keys"])
    sb.Append(string.Format("{0},", jp.Name));
foreach(JProperty jp in m["fields"])
    sb.Append(string.Format("{0},", jp.Name));
sb.Append(@") Values(");
foreach(JToken jt in m["keys"])
    sb.Append(string.Format("{0},", jt.First));
foreach(JToken jt in m["fields"])
    sb.Append(string.Format("'{0}',", jt.First));
sb.Append(")");
s = sb.ToString();
s= s.Replace(",)", ")");
//[s] variable stores insert command text


Результат:
INSERT INTO master_table (id,branch_id,name,address,phone) Values(1,1,'bar','fleet street','555')


Примечание: Вы должны скорее использовать параметризованный запрос[^] вместо сцепленных строк, чтобы избежать SQL-инъекция[^] . Итак, ваша команда должна принять такую форму:
INSERT INTO table_name (<field_list>) VALUES (<parameters_list>)

Затем вы должны добавить параметр в ParameterCollection.
Видеть:
Коллекции Sqlparametercollection Класса (Система.Данных.В Sqlclient) | Майкрософт Документы[^]
Класс OleDbParameterCollection (System.Data.OleDb) | Microsoft Docs[^]



[Правка #1]
Наконец, я бы предложил создать вспомогательный класс:
public static class JsonHelper
{
	public static string GetInsertStatement(JToken mastertoken)
	{
		return string.Format("INSERT INTO {0}({1}) VALUES({2});",
			mastertoken["table"], 
			GetFieldParameterNames(mastertoken),
			GetFieldParameterNames(mastertoken, false));
	}

	static string GetFieldParameterNames(JToken mastertoken, bool fieldOnly = true)
	{
		string p = fieldOnly ? string.Empty : "@";
		return string.Concat(string.Join(", ", mastertoken["keys"].Cast<JProperty>().Select(jp=> p + jp.Name)),
			", ", string.Join(", ", mastertoken["fields"].Cast<JProperty>().Select(jp=> p + jp.Name)));
	}
	
	public static List<SqlParameter> GetSqlParams(JToken mastertoken)
	{
		List<SqlParameter> para = new List<SqlParameter>();
		foreach(JToken jt in mastertoken["keys"])
			para.Add(new SqlParameter("@" + jt.ToObject<JProperty>().Name, jt.First));
		foreach(JToken jt in mastertoken["fields"])
			para.Add(new SqlParameter("@" + jt.ToObject<JProperty>().Name, jt.First));
		return para;
	}

}


Использование:
JObject jo = JObject.Parse(json);
JToken m = jo["master"];
string connectionstring = "Server=myServerAddress;Database=myDataBase;User Id=myUsernamePassword=myPassword;"; //change connection string
using(SqlConnection connection  = new SqlConnection(connectionstring))
{
    using(SqlCommand command = new SqlCommand(JsonHelper.GetInsertStatement(m), connection))
    {
        //connection.Open();
        List<SqlParameter> lsp = JsonHelper.GetSqlParams(jo["master"]);
        foreach(SqlParameter sqp in lsp)
            command.Parameters.Add(sqp);
        //command is ready to use ;)
    }
}


заключительное Примечание: Это не элегантное решение, а идея для улучшения.


ahmed_sa

Хорошо это очень хорошо не могли бы вы пожалуйста если это возможно изменить код выше с параметризованным запросом
я спрашиваю и читаю в google, что предотвращает SQL-инъекцию, так что вы можете изменить или сказать мне, что я изменяю в запросе выше, чтобы сделать его параметризованным запросом

Maciej Los

Какой движок базы данных?

ahmed_sa

sql server 2012

Maciej Los

См. обновленный ответ.
Удачи вам!