Laden...

Serialisierung von Klassen in CouchDB

Erstellt von Kurz&Gut vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.768 Views
K
Kurz&Gut Themenstarter:in
2 Beiträge seit 2018
vor 6 Jahren
Serialisierung von Klassen in CouchDB

Hallo Leute,

ich bin momentan dabei eine kleine Website zu erstellen, welche eine Benutzer/ Berichte/Aufgabenverwaltung enthält. Als Datenbank verwende ich die NoSQL Datenbank CouchDB, welche auf einem Apache Server unter Linux läuft.

Nun habe ich ein Problem, welches ich anhand eine kleines Beispiels erläutern möchte:

Momentan habe ich mehrere Modelle(C#) welche den selben Aufbau wie die Dokumente in CouchDB haben. Über die HTTP API ziehe ich mir die Dokumente und wandle den Response JSON String mit JSON.NET in die gewünschten Objekte um, was auch gut klappt wenn der Aufbau stimmt.

Da NoSQL Datenbanken aber schemalos sind und ich in CouchDB auch viele Möglichkeiten habe wie meine Daten angezeigt werden, ändert sich dementsprechend auch die Struktur des JSON Strings.

Nun wäre meine Frage wie ich JSON Strings, welche sich von der Struktur her unterscheiden können, auf meine C# Modelle übertrage/mappe?

Muss ich dann für jede Abfrage ein eigenes Modell erstellen?
Muss ich den kompletten String durchlaufen und dann Token für Token schauen ob dieses zu einem Feld in meiner gewünschten Klasse passt?
Sollte ich die Abfragen so gestalten das der Aufbau immer gleich bleibt?

Hier nochmal ein Beispiel damit man sich es evtl. besser vorstellen kann was ich mit verscheidenen Strukturen bei den JSON Strings meine:


//JSON String wenn ich per _find(HTTP API) ein Dokument abrufe

{
    "docs": [
        {
            "_id": "MeineID",
            "_rev": "1-54f8e950cc338d2385d9b0cda2fd918e",
            "year": 2018,
            "title": "Normales Dokument"
        }
    ]
}

//Nun will ich bspw. alle Aufgaben eines Benutzers per _view abfragen
{
    "total_rows": 5,
    "offset": 0,
    "rows": [
        {
            "id": "id",
            "key": "key",
            "value": {
                "_id": "id",
                "_rev": "rev",
                "userID": "userID"
            }
        },
        {
            "id": "id",
            "key": "key",
            "value": {
                "_id": "id",
                "_rev": "rev",
                "userID": "userID",
                "Date": "2018-01-29",
                "Description": "desc",
                "Text": "test"
            }
        }
    ]
//Das C# Modell sieht wie folgt aus
public class XXX {
                public string _id {get; set;}
                public string _rev {get; set;}
                public string userID {get; set;}
                public DateTime Date {get; set;}
                public string Description {get; set;}
                public string Text {get; set;}
}


Falls mir jemand einen Tipp geben könnte,in welche Richtung ich mich da informieren muss wäre das echt super.

Vielen Dank für eure Zeit!

16.834 Beiträge seit 2008
vor 6 Jahren

Prinzipiell hat dieses Verhalten nichts mit NoSQL zutun, sondern mit CouchDB.

Im Gegensatz zu den meisten NoSQL-Datenbanken kennt CouchDB nicht das Konzept von Collections.
In CouchDB ist das leider alles in einem Topf und Du kannst hier nicht so einfach mappen, wie in CosmosDB oder MongoDB.

Im Prinzip musst Du ein eigenes Feld pflegen, das Dir sagt welcher Typ das ist. Dann kannst Du das in der Logik auch abdecken und so serialisieren.
Siehe zB auch
Can i create multiple collection per database?

Ich habe auch dem Thema den passenden Titel verpasst.

K
Kurz&Gut Themenstarter:in
2 Beiträge seit 2018
vor 6 Jahren

Hallo Abt,

erstmal danke für die Anpassung des Titels und deine Antwort.

Ich denke das ich mich wohl zu schwammig bzw. zu blöd ausgedrückt habe was mein Problem ist:
Serialisieren an sich ist nicht mein Problem. Ich gebe bspw. in meine "Aufgaben-Form" die Daten ein, binde diese Daten an meine C# Klasse, serialisiere dieses mit Json.Net und schicke es in die Datenbank - simpel.

Nun kommen wir aber zu meinem "Design/Denkproblem".

In dem von dir geposteten Link schlägt die beste Antwort ja vor Views zu benutzen, welche die "typen" gruppiert. Das selbe mache ich ebenfalls, bloß das mein View eben alle Aufgaben nach dem Benutzer gruppiert. Jetzt frage ich den View in meinem Programm ab und bekomme dann dementsprechend ein JSON String mit diversen Metadaten und einer Collection von Dokumenten. Nun möchte ich aber auch die Möglichkeit haben einfach nur eine Aufgabe über eine ID abzufragen, was dann per _find(HTTP API) einen von der Struktur her anders aufgebauten JSON String zurückliefert. Wie die jeweiligen Strings aussehen, habe ich ja im Eingangspost gezeigt.

UND jetzt kommt der Knackpunkt:

Wie stelle ich es an das ich beide "JSON String Varianten" in mein Aufgabenmodell deserialisieren kann?
Wenn ich die _find Methode benutze, bekomme ich genau ein Dokument zurück was ich auch super in genau ein Aufgaben Objekt umwandeln kann.
Wenn ich ein View abfrage, sind zum einen Felder dabei welche im Aufgabenmodell nicht vorhanden sind, zum anderen muss ich dann auch aus dem Row-Array eine List<Aufgaben> bekommen.

Nun wäre meine Frage eben ob man für solche Fälle einfach verschiedene C# Modelle/Klassen erstellt oder ob es Sinn macht eine Klasse zu schreiben welche den String durchläuft, schaut ob es Felder gibt welche auch in meiner C# Klasse vorhanden sind und diese dann dementsprechend befüllt. Oder ich habe momentan die falsche Auffassung darüber was ich eigentlich genau möchte.

16.834 Beiträge seit 2008
vor 6 Jahren

Wenn Du Views erzeugst, die ein anderes Datenmodell haben, dann solltest Du dafür extra Klassen verwenden.
Mit Hilfe von OOP und Generics kannst Du da aber natürlich eine entsprechende Wiederverwendbarkeit erzeugen.

Aber ja, das ist in CouchDB mit dem Prinzip Database per User eben nicht ganz so einfach.