Ich bin ein Anfänger in C# und habe gekämpft, um dieses Problem zu lösen.Deserialise JSON und die Datentypen
- Ich habe eine JSON-Datei.
- Ich muss es deserialisieren und die Daten in SQL einfügen.
Die Json-Datei sieht etwa so aus:
{ "records": [ { "class": "Abc", "id": "7720170378514849999", "fields": { "name": "xyz", "created_at": "2015-02-26 15:06:48 UTC", "updated_at": "2017-05-08 15:31:45 UTC", "domain": "domainname", "month": null, "secure": true, "filters": null, "users_counter": 373 }, "links": { } }, { "class": "User", "id": "7765907511856219999", "fields": { "first_name": "aaa", "last_name": "bbb", "email": "[email protected]", "timezone": null, "local": null, "unsubscribe": false, "address_verified": false }, "links": { "Abc_id": "7720170378514849999" } }, }
Mein Code so weit:
public void doConvert() { string unzippedFileName = "c:\\tar\\finish\\UnzippedFile.json"; List<dynamic> allEntities = new List<dynamic>(); try { var deserialisedJson = JsonConvert.DeserializeObject<dynamic> (System.IO.File.ReadAllText(@unzippedFileName)); var records = deserialisedJson.records; foreach (var item in records) { string itemString = item.ToString(); var deserialisedItem = JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>> (itemString); var className = deserialisedItem["class"]; var classId = deserialisedItem["id"]; dynamic classFields = deserialisedItem["fields"]; var deserialisedClassFields = JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>> (classFields.ToString()); dynamic classLinks = deserialisedItem["links"]; var deserialisedClassLinks = JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>(classLinks.ToString()); ParseIntoType(className); ParseIntoType(classId); foreach (KeyValuePair<dynamic, dynamic> entry in deserialisedClassFields) { ParseIntoType(entry.Key); } foreach (KeyValuePair<dynamic, dynamic> entry in deserialisedClassLinks) { ParseIntoType(entry.Key); } buildsqlstatements() // My issue is here } } catch (Exception ee) { Log.ErrorFormat("Exception:{0}", ee.ToString()); } } public void ParseIntoType(dynamic itemTobeParsed) { new Dictionary<Type, Action>{ {typeof(bool),() => boolEntityList.Add(itemTobeParsed)}, {typeof(int), () => intEntityList.Add(itemTobeParsed)}, {typeof(BigInteger), () => bigIntEntityList.Add(itemTobeParsed)}, {typeof(double), () => doubleEntityList.Add(itemTobeParsed)}, {typeof(DateTime), () => dateTimeEntityList.Add(itemTobeParsed)}, {typeof(string), () => stringEntityList.Add(itemTobeParsed)}, {typeof(TextReader), () => textEntityList.Add(itemTobeParsed)}, }[itemTobeParsed.GetType()](); }
Details:
Die Idee ist, alles zu löschen, die in ist die Datenbank und neu erstellen alles bei jedem Lauf. So wird es die Tabellen löschen/löschen und die gleiche Tabelle mit den neuesten Daten neu erstellen. Zum Beispiel für Benutzer Tabelle, ich werde zuerst fallen, wenn eine (von gestern) Users_temp Tabelle dort ist, dann erstellen Users_temp Tabelle, fügen Sie die neuesten Daten in diese Tabelle, dann fallen Benutzer Tabelle und dann umbenennen Users_temp Benutzer Tabelle . Mein Problem hier ist, dass, um die Tabelle Users_temp zu erstellen, ich seine Spaltentypen definieren muss. Also muss ich den Datentyp von first_name erhalten, der als String kommen würde und dann muss ich ihn irgendwie auf varchar (255) abbilden und dann die sql-Anweisung erstellen.
Tabelle Benutzer erstellen ( first_name varchar (255) Nachname varchar (255) Zeitzone Datumzeit );
//string createTmpTable = "create table "+className+" ((column = deserialised key from fields, datatype = its datatype))";
Im Moment wird alles als Zeichenfolge geparst analysiert. Sogar die Zeitzone oder irgendwelche int-Daten werden als String analysiert. Daher kann ich die SQL-Anweisung nicht erstellen, weil ich nicht den richtigen Datentyp erhalte. Ich gehe davon aus, weil diese Zeilen ist:
foreach (var item in records)
{
string itemString = item.ToString();
var deserialisedItem =
JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>(itemString);
, weil ich den Artikel itemString bin Umwandlung, alles, was ein String wird. JsonConvert.DeserializeObject nimmt nur String-Parameter, so dass ich dort nichts anderes übergeben kann. Gibt es eine Möglichkeit, den ursprünglichen Datentyp dort wiederherzustellen?
Nicht, wenn es entlang überall nicht weitergegeben wird. Ihre beste Vermutung an diesem Punkt ist, ein Modell zu erstellen, das eine Zeile in Ihrem JSON enthalten kann, und Ihre Deserialisierung kann die Werte entsprechend Ihrem Modell umwandeln oder analysieren. –
Danke Timothy. Ja, ich dachte daran, ein Modell zu erstellen, aber wie Sie sehen, haben die Klasse Benutzer und die Klasse Abc unterschiedliche Werte im Knoten "Felder". Es gibt Tausende von Klassen in der JSON-Datei und ich kann kein Modell für jede Klasse verwenden.Darüber hinaus ist die Anforderung, die mir gegeben wird, dass sie dynamisch genug sein muss, um jeden Klassentyp, der in Zukunft kommt oder kommen wird, zu empfangen und zu analysieren, seinen Datentyp zu erhalten und dynamisch in die Tabelle einzufügen. Wie würde ich das tun, ohne den JSON zu seiner jeweiligen Klasse zu deseralisieren? – freshman8
das ist ziemlich schwierig, vielleicht "sichere" große/sichere Datentypen basierend auf der Art, wie die Daten in JSON notiert werden? (wenn es in "" ", aber nicht in eine Datumsnotation eingeschlossen ist, ist es wahrscheinlich eine" Zeichenkette ", wenn nicht umbrochen und keine Dezimalpunkte, nehme an, dass es ein' long' ist, wenn es einen Dezimalpunkt hat, nehme eine 'dezimal' an, usw.?) –