SQLite.net SQLiteFunction在Linq to SQL中不起作用

我使用System.Data.SQLite.SQLiteFunction在C#中创建了一些自定义SQLite函数。 它在使用SQLiteDataAdapter执行查询时效果很好, 但它不起作用,但是,当使用Linq to SQL时,我收到错误,指出该函数不存在

我想底线是, 我怎样才能让Custom SQLiteFunctions在Linq to SQL中运行? 要么让它们加载它们应该的方式,要么通过修改SQLite.Net的源代码使它们成为dll的一部分?

注意:我理解entity framework是首选,这是遗留应用程序,我没有选项来更改它。 我尝试手动将函数绑定到DataContext.Connection,没有骰子。


有关尝试修改System.Data.SQLite的背景:我尝试下载源代码,我可以从源代码成功构建,但源代码对我来说有点令人费解。

  • 在System.Data.SQLite.2012项目中,项目中不包含任何文件,但所有源文件都存在于实际文件夹中。 它们似乎包含在名为System.Data.SQLite.Files.targets的文件的解决方案中。 这对我来说是一个奇怪的设置。
  • 我将自定义函数添加到项目文件夹中,但没有将它们包含在项目中,就像所有其他文件一样。 然后我将它们添加到System.Data.SQLite.Files.targets中。
  • 我构建了解决方案,它们确实出现在程序集中。 虽然我似乎可以将文件添加到程序集和构建中,但修改现有代码似乎没有任何影响。
  • 我进入了SQLiteConnection类并在Open方法中添加了一个新的Exception,我在关键位置添加了Console.Writeline,我在现有代码中修改的任何内容似乎都没有进入已编译的程序集。

这样做的目的是尝试将我的自定义函数构建到System.Data.SQLite.dll中,而不是依赖于通过reflection自动加载。

就在那一刻,我从这个问题中找到了这个漂亮的片段

// 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])); } } 

但没有找到如何使用它。 现在有一个SQLiteConnection.BindFunction方法。 这很难看,所以我做了一个小扩展方法:

 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); } 

现在你只需要

 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 } 

现在你如何在LINQ to SQL中做到这一点,我不知道因为我在LINQ IQueryProvider上有自己的SQL。 这是使用基本IDbConnection,IDbCommand,IDbDataParameter和IDataReader接口以及自定义SQLiteFunction实现的方法。