2013-07-03 18 views
9

Sto cercando qualcuno che abbia fatto qualcosa sulla falsariga di interrogare le stringhe JSON con Entity Framework.Entity Framework per l'interrogazione di stringhe JSON in SQL Server

Dovrei dare un piccolo background su cosa sto cercando di fare qui. Il database che sto utilizzando è per un motore di workflow su cui sto lavorando. Gestisce tutti i dati del flusso di lavoro e consente anche di memorizzare alcuni dati personalizzati come una stringa JSON. Il motore del flusso di lavoro che sto utilizzando gestisce la serializzazione e la de-serializzazione delle stringhe JSON su una base per richiesta, ma nel caso in cui vorrei fare una query e filtrare in base ai valori nella stringa JSON, dovrei tirare l'intera tabella in memoria e deserializzare tutte le voci e quindi filtrare. Questo è, per ovvi motivi, non accettabile. Il motivo è che vogliamo un singolo database del flusso di lavoro che possa essere utilizzato per tutte le applicazioni che utilizzano questo motore di flusso di lavoro e stiamo cercando di evitare di dover eseguire visualizzazioni incrociate del database per separare i database specifici dell'applicazione per ottenere i dati personalizzati. Poiché nella maggior parte dei casi, i dati delle richieste personalizzate che vengono archiviati come stringhe JSON sono relativamente semplici e, nella maggior parte dei casi, non sono necessari per le query, in base alla progettazione. Ma nel caso in cui abbiamo bisogno di fare ricerche personalizzate, abbiamo bisogno di un modo per essere in grado di analizzare questi oggetti JSON personalizzati. E spero che questo possa essere fatto dinamicamente con Entity, quindi non devo scrivere processi aggiuntivi per l'interrogazione di tipi specifici di oggetti. Idealmente avrei solo una libreria che usa l'entità per consentire l'interrogazione di qualsiasi struttura di dati JSON.

Ho iniziato con una funzione di database che ho trovato che analizza JSON e restituisce una tabella appiattita che contiene i valori (ID oggetto padre, nome, valore e tipo). Quindi ha importato quella funzione nel mio modello di entità. Ecco un link a dove ho preso il codice. Articolo abbastanza interessante.

Consuming JSON Strings in SQL Server

Ecco le basi di dove sono a.

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

Nell'esempio di codice precedente, oggetto di richiesta è il flusso di lavoro di base Oggetto di richiesta. RequestData() è un metodo di estensione sul tipo

DbSet<Request> 

e parseJSON è il nome della mia funzione di database.

Il mio piano è quello di scrivere una serie di metodi di estensione che filtrerà il Queryables

IQueryable<parseJSON_result> 

Così, per esempio, se ho un oggetto che assomiglia a questo.

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

sarei stato in grado di fare qualcosa di simile

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

o qualcosa del genere. Il metodo .Where accetta Take RequestData(), che è un IQueryable che contiene il JSON analizzato, filtra e restituisce il nuovo risultato IQueryable.

Quindi la mia domanda è, qualcuno ha mai fatto qualcosa del genere? In tal caso, che tipo di approccio hai adottato? Il mio intento originale era quello di fare qualcosa di stile del dizionario, ma sembrava troppo difficile. Qualsiasi pensiero, idea, suggerimento, saggezza, sarebbe molto apprezzato. Ci ho lavorato per un po 'e mi sento come se non fossi arrivato così lontano. Il che è principalmente dovuto al fatto che non riesco a decidere come voglio che la sintassi sia visibile, e non sono sicuro se dovrei fare più lato del database di lavoro.

Questa era la mia idea originale per la sintassi, ma non potevo eseguire l'operatore [] senza idratare l'oggetto.

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

So che questo è un bel post lungo, quindi se hai letto fin qui, grazie per solo prendendo il tempo di leggere il tutto.

+0

Si potrebbe deserializzare json respone a una classe poco e quindi utilizzarlo –

+0

Ho utilizzato l'approccio suggerito da RAZER. Crea un POCO e usa Json.NET per la serializzazione e la deserializzazione. – jake

risposta

0

Ciò che si potrebbe fare è creare una funzione definita dall'utente CLR SQL Server, quindi utilizzarla dalla query.

Vedi questo link https://msdn.microsoft.com/en-us/library/ms131077.aspx

Vorrei pensare che un funzioni con valori di tabella è più adatto per la vostra situazione.

1

A partire da SQL Server 2016 esistono FOR JSON e OPENJSON, equivalenti a FOR XML e OPENXML. Puoi indicizzare su espressioni che fanno riferimento a JSON archiviate nelle colonne NVARCHAR.

+0

Tuttavia Entity Framework supporta questo? – Zapnologica

0

questa è una risposta molto tardi, ma per chi è ancora alla ricerca ...

Come dice @Emyr, SQL 2016 supporta l'esecuzione di query all'interno di colonne JSON utilizzando le istruzioni JSON_VALUE o OPENJSON.

Entity Framework non supporta ancora direttamente questo, ma è possibile utilizzare il metodo SqlQuery per eseguire un comando SQL raw direttamente sul database che può eseguire query nelle colonne JSON e salva query e deserializzazione di ogni riga per eseguire una query semplice .

Problemi correlati