SQLiteFunction在Linq to SQL中不工作

本文关键字:工作 SQL to Linq SQLiteFunction | 更新日期: 2023-09-27 18:08:37

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

我想底线是,我怎么能得到自定义SQLiteFunctions工作在Linq到SQL?要么通过让它们以它们应该的方式加载,要么通过修改SQLite的源代码。Net所以它们是dll的一部分?

注意:我理解实体框架是首选,这是遗留的应用程序,我没有选项来改变这一点。我尝试手动将函数绑定到DataContext。连接,没有骰子。


关于试图修改System.Data.SQLite的后台:我试着下载源代码,我可以成功地从源代码构建,但源代码对我来说有点令人费解。

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

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

SQLiteFunction在Linq to SQL中不工作

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

// 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<SQLiteFunctionAttribute>().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来做到的。