問題描述
我使用 System.Data.SQLite.SQLiteFunction 在 C# 中創建了一些自定義 SQLite 函數.使用 SQLiteDataAdapter 執行查詢時效果很好,它不起作用,但是,當使用 Linq to SQL 時,我收到錯誤消息,指出該函數不存在.
I've created a handful of custom SQLite functions in C# using System.Data.SQLite.SQLiteFunction. It works great when using SQLiteDataAdapter to execute queries, it does not work, however, when using Linq to SQL I get errors stating that the function does not exist.
我想最重要的是,我怎樣才能讓自定義 SQLiteFunctions 在 Linq to SQL 中工作?要么讓它們按照預期的方式加載,要么通過修改SQLite.Net 所以它們是 dll 的一部分?
I guess the bottom line is, how can I get the Custom SQLiteFunctions to work in Linq to SQL? Either by getting them to load the way they are supposed to or by modifying the source code of SQLite.Net so they are part of the dll?
注意:我了解 Entity Framework 是首選,這是遺留應用程序,我無法更改它.我嘗試將函數手動綁定到 DataContext.Connection,沒有骰子.
Note: I understand Entity Framework is preferred, this is legacy application and I do not have the option to change this. I tried binding the functions manually to the DataContext.Connection, no dice.
嘗試修改 System.Data.SQLite 的背景:我嘗試下載源代碼,我可以成功地從源代碼構建,但是源代碼對我來說有點令人費解.
Background regarding an attempt to modify System.Data.SQLite: I tried downloading the source code, I can successfully build from source, but the source code is a little puzzling to me.
- 在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 中,而不是依賴于通過反射自動加載.
The goal of this was to try and build my custom functions into the System.Data.SQLite.dll rather than rely on auto loading through reflection.
推薦答案
就在那一刻我發現了這個不錯的片段 來自這個問題
Just that moment I found this nice snippet 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 方法.很丑所以我做了一個小擴展方法:
But didn't find how to use it. Now there's a SQLiteConnection.BindFunction method. It's ugly so I made a little extension method:
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)test'
// looks for the word 'test', case-insensitive in a string column
}
現在如何在 LINQ to SQL 中執行此操作,我不完全知道,因為我在 LINQ IQueryProvider 上有自己的 SQL.這是使用基本 IDbConnection、IDbCommand、IDbDataParameter 和 IDataReader 接口以及自定義 SQLiteFunction 實現的方法.
Now how you can do it in LINQ to SQL, I don't exactly know because I've got my own SQL on LINQ IQueryProvider. This is how you can do it with the basic IDbConnection, IDbCommand, IDbDataParameter and IDataReader interfaces and your custom SQLiteFunction.
這篇關于SQLite.net SQLiteFunction 在 Linq to SQL 中不起作用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!