2016-03-23 2 views
0

Ich habe den StackExchange.Redis-Client zum Speichern von Schlüsselwertpaaren verwendet.Wie kann ich primitive C# -Typen oberhalb von RedisValue beibehalten, wenn ich StackExchange.Redis verwende

Ich habe ein verschachteltes dynamisches Objekt (JObject) und ich, das Objekts zu einer Schlüssel-Wert-Struktur, die etwas abflachen wie folgt aussieht: nehmen

Läßt die JObject wie folgt aussieht:

"Root": 
{ 
    "Obj1": 
    { 
     "Prop":12, 
     "Prop2": "StringValue" 
    } 
} 

ich diese abzuflachen Objekt in einen Dictionary<string, object>, die Schlüssel-Wert-Paare, die wie folgt aussehen erzeugt:

key: "Root.Obj1.Prop" | value: 12 
key: "Root.Obj1.Prop2" | value: "StringValue" 

ich bin mit 012.und nicht string, da mein Client weiß, wie man mit verschiedenen Primitiven umgeht (die nicht immer strings sind).

Der spezifische Redis-Client weist eine RedisValue Struktur aus, die implizite Castings für mehrere Typen, jedoch nicht für Objekte enthält.

Also musste ich mein Wörterbuch in verschiedene primitive enumerables zu schaffen, um RedisValues ​​und zu „halten“ ihre ursprünglichen Typen aufgeteilt:

var strs = dic.Where(kvp => kvp.Value is string).Select(kvp => new HashEntry(kvp.Key, (string)kvp.Value)); 
var ints = dic.Where(kvp => kvp.Value is int).Select(kvp => new HashEntry(kvp.Key, (int)kvp.Value)); 

jeder Wert nun in der ints enumerable hat eine isInteger Eigenschaft gleich wahr .

Also nachdem ich Redis mit diesen Werten gesetzt habe, hole ich jetzt die Schlüsselwerte von Redis und ich habe eine Menge RedisValues ​​in meiner Hand. Ich nehme einen RedisValue, bei dem eine IsInteger-Eigenschaft gleich true ist, und sieht, dass dieser Status nicht wirklich beibehalten wurde.

Meine Fragen:

  1. Gibt es eine Möglichkeit, die wirklichen primitiven Typen zwischen den Sätzen beibehalten kann und wird? Ich verstehe, ich habe ein paar Boxen \ Unboxing Probleme, indem Sie sie als Objekte, aber ich habe viele Vorteile in dieser spezifischen App. Die Verwendung einer RedisValue-Struktur ist nichts, was ich in meiner Anwendung gerne tun würde. Ich möchte das in einer kleinen spezifischen Schicht behalten, die mit Redis kommuniziert.

  2. Wenn es keine Möglichkeit gibt, (1) zu tun, gibt es dann einen guten Grund, warum der RedisValue die IsInteger-Eigenschaft nicht zwischen den Sätzen hält und bekommt? Wenn ich den RedisValue setze, habe ich die IsInteger-Eigenschaft auf true gesetzt, und wenn ich sie hole, ist sie falsch.

Vielen Dank.

+0

Wie werden Sie die Daten in Redis abfragen? Irgendwelche Notwendigkeit, es überhaupt zu brechen? Wenn nicht, könnten Sie das JObject einfach als String mit vollständigen Typinformationen für jede Eigenschaft speichern, um eine korrekte Deserialisierung zu ermöglichen. –

+0

Ich möchte nicht den vollständigen JSON als Wert halten, da meine Datenstruktur vom Design her ein "abgeflachtes Objekt" ist. Redis passt wie angegossen zu meinem "Key-Data" -Ansatz. Da ich hinter meinem Objekt keine echte Struktur habe, möchte ich die ursprünglichen Typen beibehalten. Wenn ich einen Age-Eintrag habe, den ich mit einem int (als RedisValue) aktualisiere, möchte ich diese Daten auch als int abrufen und nicht als String. –

Antwort

3

Sie könnten einen zusätzlichen Schlüssel pro Eigenschaft mit Typinformationen schreiben, z.

Root:Obj1:Prop=12 
Root:Obj1:Prop:type=int 

Root.Obj1.Prop2=StringValue 
Root.Obj1.Prop2:type=string 

und immer zuerst den Typschlüssel abrufen, damit Sie wissen, wie der Wertschlüssel konvertiert wird.

Aber ich würde es nicht empfehlen. Stattdessen würde ich einen von zwei Standardansätzen empfehlen, je nachdem, wie Sie die Daten über Redis abfragen möchten.

  1. Karte stark typisierte Objekte Schlüssel Redis

    • geht davon aus, dass eine effiziente Abfrage über Redis Operationen ist eine Priorität
    • Hier können Sie Ihre Redis spezifischen Code in einer Mapping-Klasse
  2. lokalisieren
  3. Ein persistentes Objekt speichern

    • Grundsätzlich ein BLOB von Daten. Könnte ein vollständiges JSON-Objekt sein (vielleicht sogar vollständige Typinformationen für jede Eigenschaft - es gibt eine Option, um diese mit Json.Net zu aktivieren) oder ein Array von Bytes mit Hilfe von Protobuf
    • Angenommen, Sie verwenden Redis nur zum Speichern; was ist OK
+1

Danke für die Antwort. Ich weiß, ich kann schreiben und zusätzliche Eigenschaft für Typ Info und ich möchte nicht dorthin gelangen. Ich kann keinen starken Typ zuordnen, da mein Json-Objekt vollständig dynamisch ist (ein Third-Party-Service gibt mir kleine Teile von Daten und ich baue diesen Json im laufenden Betrieb). Ich möchte die Datenstruktur beibehalten, wie es jetzt ist, da ich andere Einschränkungen habe, die es effizient und lesbar machen. Vielen Dank für die Antwort. +1 auf die Mühe. –

+1

np, danke für die Rückmeldung. Angesichts Ihrer Umstände vermute ich, dass der BLOB-Ansatz am besten für Sie funktioniert. Sie erwähnen, dass Sie das Objekt wirklich aufschlüsseln müssen, aber ohne Beispiele für die Arten von Redis-Abfragen, die Sie machen würden, ist es nicht möglich, Ihnen zu helfen. Es könnte sein, dass meine Antwort nicht das ist, was Sie hören wollten, aber wenn Sie denken, dass sie die Frage adressiert, dann markieren Sie sie bitte als akzeptiert. Vielen Dank –

Verwandte Themen