SQLite.net SQLiteFunction在Linq to SQL中不工作

41ik7eoe  于 2023-11-21  发布在  SQLite
关注(0)|答案(2)|浏览(129)

我用System.Data.SQLite.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQLiteFunction.SQL
我想底线是,**我如何才能让自定义SQLiteFunctions在Linq to SQL中工作?**要么让它们以它们应该的方式加载,要么修改SQLite. Net的源代码,使它们成为DLL的一部分?
注意事项:我知道实体框架是首选,这是遗留应用程序,我没有选择改变这一点。我试图手动绑定函数到DataContext。连接,没有骰子。
关于试图修改System.Data.SQLite的背景:我试着下载源代码,我可以成功地从源代码构建,但源代码对我来说有点困惑。

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

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

ntjbwcob

ntjbwcob1#

就在那一刻,我发现了这个漂亮的片段from this question

// 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来做到这一点。

k7fdbhmy

k7fdbhmy2#

我知道这有点晚了,但是你不能在实际使用SQLiteFunction.RegisterFunction(typeof(RegExSQLiteFunction));之前在代码中的某个地方调用它吗?

相关问题