SQLite.net SQLiteFunction non funziona in Linq to SQL

Ho creato una manciata di funzioni SQLite personalizzate in C # usando System.Data.SQLite.SQLiteFunction. Funziona perfettamente quando si utilizza SQLiteDataAdapter per eseguire query, ma non funziona, tuttavia, quando si utilizza Linq su SQL, si verificano degli errori che indicano che la funzione non esiste .

Immagino che la linea di fondo sia, come posso far funzionare le funzioni SQLite personalizzate in Linq in SQL? O facendoli caricare nel modo in cui dovrebbero o modificando il codice sorgente di SQLite.Net in modo che facciano parte della dll?

Nota: Comprendo che Entity Framework è preferito, questa è un’applicazione legacy e non ho la possibilità di cambiarla. Ho provato a bind le funzioni manualmente a DataContext.Connection, senza dadi.


Informazioni generali su un tentativo di modifica di System.Data.SQLite: ho provato a scaricare il codice sorgente, posso creare con successo dal sorgente, ma il codice sorgente è un po ‘sconcertante per me.

  • Nel progetto System.Data.SQLite.2012, non ci sono file inclusi nel progetto, ma tutti i file di origine esistono nella cartella effettiva. Sembrano essere inclusi nella soluzione in un file chiamato System.Data.SQLite.Files.targets. Questa è una configurazione strana per me.
  • Ho aggiunto le mie funzioni personalizzate alla cartella del progetto, ma non le ho incluse nel progetto come tutti gli altri file. Poi li ho aggiunti a System.Data.SQLite.Files.targets.
  • Ho costruito la soluzione e appaiono nell’assemblea. Sebbene possa sembrare che aggiunga file all’assemblaggio e alla build, la modifica del codice esistente sembra non avere alcun effetto.
  • Sono entrato nella class SQLiteConnection e ho aggiunto una nuova eccezione Exception nel metodo Open, ho aggiunto Console.Writeline in posizioni chiave, nulla di quello che ho modificato nel codice esistente sembra farlo nell’assembly compilato.

L’objective era quello di provare e creare le mie funzioni personalizzate nel System.Data.SQLite.dll piuttosto che fare affidamento sul caricamento automatico tramite reflection.

Proprio in quel momento ho trovato questo bel frammento di questa domanda

// from https://stackoverflow.com/questions/172735/create-use-user-defined-functions-in-system-data-sqlite // taken from http://sqlite.phxsoftware.com/forums/p/348/1457.aspx#1457 [SQLiteFunction(Name = "REGEXP", Arguments = 2, FuncType = FunctionType.Scalar)] public class RegExSQLiteFunction : SQLiteFunction { public override object Invoke(object[] args) { return System.Text.RegularExpressions.Regex.IsMatch(Convert.ToString(args[1]), Convert.ToString(args[0])); } } 

Ma non ha trovato come usarlo. Ora c’è un metodo SQLiteConnection.BindFunction. È brutto quindi ho fatto un piccolo metodo di estensione:

 public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function) { var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast().ToArray(); if (attributes.Length == 0) { throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute"); } connection.BindFunction(attributes[0], function); } 

E ora devi solo

 using (var connection = new SQLiteConnection( "Data Source=YourDB.sqlite" )) { connection.Open(); // Connection must be open to bind a function connection.BindFunction(new RegExSQLiteFunction()); // Here create a command, and try REGEXP, for example // SELECT * FROM "table" WHERE "column" REGEXP '(?i)\btest\b' // looks for the word 'test', case-insensitive in a string column } 

Ora come puoi farlo in LINQ to SQL, non lo so esattamente perché ho il mio SQL su LINQ IQueryProvider. Ecco come puoi farlo con le interfacce di base IDbConnection, IDbCommand, IDbDataParameter e IDataReader e la tua SQLiteFunction personalizzata.