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

15
我使用System.Data.SQLite.SQLiteFunction在C#中创建了一些自定义的SQLite函数。当使用SQLiteDataAdapter执行查询时,它可以很好地工作,但是当我使用Linq to SQL时出现错误,指出该函数不存在。
我的问题是,如何让自定义的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方法中添加throw new Exception,我在关键位置添加了Console.Writeline,但我修改的现有代码似乎没有进入编译后的程序集。
这样做的目的是尝试将我的自定义函数构建到System.Data.SQLite.dll中,而不是依靠反射自动加载它们。
2个回答

40

刚刚我发现了这个非常好的代码片段,来自于这个问题的链接

// from https://dev59.com/VHVC5IYBdhLWcg3w1Exq
// 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);
}

现在你只需要 <\p>
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中实现这一点,我不太清楚,因为我有自己的SQL on LINQ IQueryProvider。使用基本的IDbConnection、IDbCommand、IDbDataParameter和IDataReader接口以及您自定义的SQLiteFunction,您可以这样做。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接