10

Sto trasferendo il database del nostro prodotto su SQLite da un altro prodotto che supporta Guids. Come sappiamo, SQLite non supporta Guids. Ho creato un modello di entity framework 6 dal mio database (prima il database) e ho bisogno di creare una query da C# che paragona il Guid a uno passato dal codice.In che modo il provider SQLite Entity Framework 6 gestisce Guids?

Il problema è che non riesco a trovare alcuna documentazione su come il provider SQLite Entity Framework gestisce Guids. Una ricerca sul Web non ha trovato nulla di utile neanche per me. Solo domande sull'utilizzo di Entity Framework con SQLite.

Qualcuno può indicarmi la documentazione o forse dirmi come lavorare con Guids in un database SQLite attraverso un modello EF6?

+0

SQLite non ha un esplicito tipo di colonna GUID, ma la loro memorizzazione con il tipo di affinità 'BLOB' funziona perfettamente bene. Non so molto su Entity Framework, ma sembra che i convertitori di tipi (oltre l'enumerazione) saranno solo in EF 7. Ma GUID ha un CT o un array di byte, ecc, quindi potrebbe essere piuttosto semplice. – peterchen

+0

Li sto archiviando come BLOB nel mio modello, tuttavia, ho un problema. Il codice ha un'espressione simile a "ID == Guid ('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') che lancia un'eccezione perché il tipo di ID nel database è' Byte [] 'e la cosa a destra è un 'Guid'. Il codice in questione deve essere eseguito sul nostro client (il codice su cui sto lavorando) con SQLite e sul nostro server, dove il database è SQL Server.La stringa di espressione non può cambiare. fare qualcosa sul lato SQLite per far funzionare il confronto, ma non so cosa, ecco perché sto cercando la documentazione –

+0

In SQLite, è possibile sovrascrivere la funzione Guid(): https: // www. sqlite.org/c3ref/create_function.html (non so come funziona attraverso EF) – peterchen

risposta

3

Finalmente ho una risposta a questo problema.

Il mio problema è che il provider SQLite Entity Framework 6 non gestisce correttamente la conversione dei GUID letterali nel codice in SQL. Cioè, un'espressione Linq della forma

context.MyEntity.Where(x => x.GuidColumn == new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")) 

viene convertito nel seguente SQL:

SELECT GuidColumn, Column1, Column2, . . . Column n 
FROM MyEntity AS Extent1 
WHERE Extent1.GuidColumn = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 

Questo è sbagliato, poiché il valore memorizzato nella colonna è una matrice di byte.

Secondo this problem report on the SQLite site, risulta che il team di SQLite considera questo un errore nel provider e stanno lavorando per risolverlo nella versione 1.0.95.0. Non so quando verrà rilasciato, ma almeno lo riconoscono come un problema e lo risolveranno.

+0

Questo è male .... abbiamo deciso di archiviare i GUID come stringhe a causa di questo problema – DarkWalker

+0

Mentre non sono più in quell'azienda e non ho più accesso a quel codice, penso che ciò che abbiamo fatto è stato mettere il Guid in un Guid variabile e confrontato con quello. Come ricordo, questo è gestito correttamente. –

10

Sembra che questo sia stato risolto nella versione 1.0.95, ma nuovamente interrotto in 1.0.97. La soluzione è impostare la proprietà BinaryGUID sulla stringa di connessione su true e impostare la seguente variabile di ambiente (prima di stabilire la connessione)

Environment.SetEnvironmentVariable ("AppendManifestToken_SQLiteProviderManifest", "; BinaryGUID = True;");

Origine dati = c: \ mydb.db; Versione = 3; BinaryGUID = True;

https://www.connectionstrings.com/sqlite/

+1

Sto usando 1.0.97, ma l'impostazione della variabile di ambiente in realtà lo spezza per me. Ricevo 'System.Data.Entity.Core.ProviderIncompatibleException: il provider non ha restituito un'istanza ProviderManifest. 'E un'eccezione interna' System.ArgumentException: esiste già una voce con la stessa chiave. Tuttavia, solo la modifica della stringa di connessione funziona correttamente. – Thorarin

+1

Ottimo post! Questo ha risolto il problema per me utilizzando 1.0.99 e Entity Framework 6 – RichTurner

+0

BinaryGUID = True nel file di configurazione è tutto ciò che dovevo fare. – CrusherJoe

Problemi correlati