2013-07-03 7 views
9

Ich bin auf der Suche nach jemandem, der alles in Bezug auf die Abfrage von JSON-Strings mit dem Entity Framework getan hat.Entity Framework für die Abfrage von JSON-Zeichenfolgen in SQL Server

Ich sollte ein wenig Hintergrundinformationen über das, was ich hier versuche, geben. Die Datenbank, die ich verwende, ist für eine Workflow-Engine, an der ich gerade arbeite. Es verarbeitet alle Workflow-Daten und ermöglicht Ihnen außerdem, einige benutzerdefinierte Daten als JSON-Zeichenfolge zu speichern. Die von mir verwendete Workflow-Engine behandelt das Serialisieren und Deserialisieren der JSON-Zeichenfolgen pro Anfrage, aber für den Fall, dass ich eine Abfrage ausführen und auf Werten in der JSON-Zeichenfolge filtern möchte, müsste ich ziehen die gesamte Tabelle in den Speicher und Deinserialisierung aller Einträge und dann filtern. Dies ist aus offensichtlichen Gründen nicht akzeptabel. Der Grund dafür ist, dass wir eine einzige Workflow-Datenbank haben möchten, die für alle Anwendungen verwendet werden kann, die diese Workflow-Engine verwenden, und wir versuchen zu vermeiden, dass Datenbanksichten anwendungsspezifische Datenbanken trennen müssen, um die benutzerdefinierten Daten zu erhalten. Da in den meisten Fällen die benutzerdefinierten Anforderungsdaten, die als JSON-Zeichenfolgen gespeichert werden, relativ einfach sind, werden sie in den meisten Fällen nicht benötigt, wenn sie abgefragt werden. Aber für den Fall, dass wir benutzerdefinierte Suchvorgänge durchführen müssen, benötigen wir eine Möglichkeit, diese benutzerdefinierten JSON-Objekte analysieren zu können. Und ich hoffe, dass dies dynamisch mit Entity getan werden kann, so dass ich keine extra gespeicherten Procs für die Abfrage bestimmter Objekttypen schreiben muss. Idealerweise hätte ich nur eine Bibliothek, die Entität verwendet, um Abfragen von JSON-Datenstrukturen zuzulassen.

Ich begann mit einer Datenbankfunktion, die JSON analysiert und eine geglättete Tabelle zurückgibt, die die Werte (übergeordnete Objekt-ID, Name, Wert und Typ) enthält. Dann importierte ich diese Funktion in mein Entitätsmodell. Hier ist ein Link zu wo ich den Code bekommen habe. Ziemlich interessanter Artikel.

Consuming JSON Strings in SQL Server

Hier ist die Grundlagen, wo ich bin.

using (var db = new WorkflowEntities()) { 
    var objects = db.Requests.RequestData(); 
} 

Im obigen Codebeispiel ist Request-Objekt mein Basis-Workflow-Request-Objekt. RequestData() ist eine Erweiterungsmethode vom Typ

DbSet<Request> 

und parseJSON ist der Name meiner Datenbankfunktion.

Mein Plan ist es, eine Reihe von Erweiterungsmethoden zu schreiben, die die Queryables

IQueryable<parseJSON_result> 

So zum Beispiel filtern, wenn ich ein Objekt, das wie folgt aussieht.

RequestDetail : { 
    RequestNumber: '123', 
    RequestType: 1, 
    CustomerId: 1 
} 

ich wäre in der Lage so etwas wie

db.Request.RequestData().Where("RequestType", 1); 

oder etwas in diese Richtung zu tun. Die .Where-Methode würde RequestData() nehmen, das ein IQueryable ist, das das analysierte JSON enthält, es würde filtern und das neue IQueryable-Ergebnis zurückgeben.

Also meine Frage ist wirklich, hat jemand so etwas getan? Wenn ja, welche Art von Ansatz haben Sie gewählt? Meine ursprüngliche Absicht war, etwas Wörterbuchstil zu machen, aber es schien zu schwierig. Alle Gedanken, Ideen, Vorschläge, Weisheit, würden sehr geschätzt werden. Ich habe eine Weile daran gearbeitet, und ich habe das Gefühl, dass ich wirklich nicht so weit gekommen bin. Das liegt hauptsächlich daran, dass ich nicht entscheiden kann, wie ich die Syntax aussehen soll, und ich bin mir nicht sicher, ob ich mehr Arbeit auf der Datenbankseite machen sollte.

Das war meine ursprüngliche Idee für die Syntax, aber ich konnte den Operator [] nicht ausführen, ohne das Objekt zu hydratisieren.

db.Request.Where(req => req.RequestData()["RequestType"] == 1).Select(req => req.RequestData()["CustomerInfo"]); 

Ich weiß, dass dies ein ziemlich langen Pfosten ist, also wenn Sie bis hierher gelesen haben, vielen Dank für nur die Zeit nehmen, um das Ganze zu lesen.

+0

Sie könnten Ihre JSON-Antwort zu einer Poco-Klasse deserialisieren und dann verwenden –

+0

Ich habe den Ansatz verwendet, den RAZER vorgeschlagen hat. Erstellen Sie ein POCO und verwenden Sie Json.NET für die Serialisierung und Deserialisierung. – jake

Antwort

1

Ab SQL Server 2016 sind FOR JSON und OPENJSON vorhanden und entsprechen FOR XML und OPENXML. Sie können Indizes für Ausdrücke erstellen, die auf JSON verweisen, das in NVARCHAR-Spalten gespeichert ist.

+0

Unterstützt Entity Framework dies? – Zapnologica

0

Dies ist eine sehr späte Antwort, aber für alle, die noch auf der Suche ...

Wie @Emyr sagt, SQL 2016 unterstützt innerhalb JSON Spalten mit JSON_VALUE oder OPENJSON Aussagen abfragt. Das Entity Framework unterstützt dies nicht direkt, aber Sie können die SqlQuery-Methode verwenden, um direkt einen Raw-SQL-Befehl für die Datenbank auszuführen, der innerhalb von JSON-Spalten abfragen und die Abfrage und Deserialisierung jeder Zeile zur Ausführung einer einfachen Abfrage speichern kann .

Verwandte Themen