c# - SQLite.net SQLiteFunction no funciona en Linq a SQL
linq-to-sql system.data.sqlite (1)
Justo en ese momento encontré este buen fragmento de esta pregunta
// 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]));
}
}
Pero no encontré cómo usarlo. Ahora hay un método SQLiteConnection.BindFunction. Es feo, así que hice un pequeño método de extensión:
public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function)
{
var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast<SQLiteFunctionAttribute>().ToArray();
if (attributes.Length == 0) {
throw new InvalidOperationException("SQLiteFunction doesn''t have SQLiteFunctionAttribute");
}
connection.BindFunction(attributes[0], function);
}
Y ahora solo tienes que
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
}
Ahora, cómo puede hacerlo en LINQ to SQL, no lo sé exactamente porque tengo mi propio SQL en LINQ IQueryProvider. Así es como puede hacerlo con las interfaces básicas IDbConnection, IDbCommand, IDbDataParameter e IDataReader y su SQLiteFunction personalizada.
Creé un puñado de funciones SQLite personalizadas en C # utilizando System.Data.SQLite.SQLiteFunction. Funciona muy bien cuando se usa SQLiteDataAdapter para ejecutar consultas, no funciona, sin embargo, cuando uso Linq to SQL obtengo errores que indican que la función no existe .
Supongo que la conclusión es, ¿cómo puedo hacer que las funciones SQLite Custom funcionen en Linq to SQL? ¿Haciendo que se carguen de la manera en que se supone que deben hacerlo o modificando el código fuente de SQLite.Net para que formen parte del dll?
Nota: Entiendo que Entity Framework es preferido, esta es una aplicación heredada y no tengo la opción de cambiar esto. Traté de vincular las funciones manualmente a DataContext.Connection, sin dados.
Antecedentes con respecto a un intento de modificar System.Data.SQLite: Intenté descargar el código fuente, puedo compilarlo correctamente desde la fuente, pero el código fuente me resulta un poco desconcertante.
- En el proyecto System.Data.SQLite.2012, no hay archivos incluidos en el proyecto, pero todos los archivos de origen existen en la carpeta real. Parecen estar incluidos en la solución en un archivo llamado System.Data.SQLite.Files.targets. Esta es una configuración extraña para mí.
- Agregué mis funciones personalizadas a la carpeta del proyecto, pero no las incluí en el proyecto como todos los otros archivos. Luego los agregué a System.Data.SQLite.Files.targets.
- Construí la solución y aparecen en el ensamblaje. Aunque parezco agregar archivos al ensamblado y a la compilación, la modificación del código existente parece no tener ningún efecto.
- Ingresé a la clase SQLiteConnection y agregué una excepción nueva en el método Open, agregué Console.Writeline en lugares clave, y nada de lo que modifico en el código existente parece llegar al ensamblado compilado.
El objetivo de esto era intentar crear mis funciones personalizadas en System.Data.SQLite.dll en lugar de confiar en la carga automática a través de la reflexión.