gpt4 book ai didi

ios - Xamarin.iOS 中的自定义 SQLite 函数

转载 作者:行者123 更新时间:2023-12-02 00:03:43 24 4
gpt4 key购买 nike

我正在 Xamarin.iOS 上开发 Sqlite 的自定义功能。我从这里得到答案:Show markers on map within a given radius (Xamarin.Android)但我遇到了问题

Attempting to JIT compile method '(wrapper native-to-managed) Mono.Data.Sqlite.SqliteFunction:ScalarCallback (intptr,int,intptr)' while running with --aot-only.

在堆栈上搜索后,我发现这是一个解决方案: custom functions SQLite with Mono但解决方案的提及对我来说很难理解。

我不确定如何使用 MonoPInvokeCallbackAttribute 注释方法并使其静态,因为 SqliteFunction 类中的方法被重写,因此无法使其静态。如果有人可以帮助我理解该解决方案或提供该解决方案中缺少的步骤,那就太好了。

最佳答案

我使用流行的sqlite-net(作者:Frank A. Krueger),它又使用SQLitePCLRaw.bundle_greenSQLitePCL.raw (均由埃里克·辛克创作)。

因此,您可以使用基于 SQLitePCLRaw.ugly 的 API 轻松设置和访问 SQLite UDF。

基于 Xamarin.iOSSQLite 用户定义函数 (UDF):

delegate void SQLiteCallback(sqlite3_context ctx, object user_data, sqlite3_value[] args);
[MonoPInvokeCallback(typeof(SQLiteCallback))]
static void UDFDistanceFunction(sqlite3_context ctx, object user_data, sqlite3_value[] args)
{
double radius = 6367;
var lat1 = raw.sqlite3_value_double(args[0]);
var lng1 = raw.sqlite3_value_double(args[1]);
var lat2 = raw.sqlite3_value_double(args[2]);
var lng2 = raw.sqlite3_value_double(args[3]);
var result = radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((lat2 * (Math.PI / 180) - lat1 * (Math.PI / 180)) / 2.0), 2.0) + Math.Cos(lat1 * (Math.PI / 180)) * Math.Cos(lat2 * (Math.PI / 180)) * Math.Pow(Math.Sin((lng2 * (Math.PI / 180) - lng1 * (Math.PI / 180)) / 2.0), 2.0)))));
raw.sqlite3_result_double(ctx, result);
}

用法:

使用sqlite-net-pcl来设置表、加载/更新数据......

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
var dbName = Path.Combine(Path.GetTempPath(), "StackOverflow.db");
var db = new SQLiteConnection(dbName, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, true);
db.CreateTable<BarLocations>();
db.Insert(new BarLocations()
{
name = "FOOBAR", lat = 47.60357, lng = -122.3295
});

使用 SQLitePCLRaw.ugly 创建和查询 SQLite UDF

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
var dbName = Path.Combine(Path.GetTempPath(), "StackOverflow.db");
using (sqlite3 dbRaw = ugly.open(dbName))
{
dbRaw.create_function("distance", 4, null, UDFDistanceFunction);
double currentLatitude = 47.0;
double currentLongitude = -122.0;
var sql = $"SELECT * FROM barlocations WHERE distance('{currentLatitude.ToString()}', '{currentLongitude.ToString()}', barlocations.lat, barlocations.lng) <= 100 ;";
var locs = dbRaw.query<BarLocations>(sql);
foreach (var loc in locs)
{
Console.WriteLine(loc.name);
}
}

关于ios - Xamarin.iOS 中的自定义 SQLite 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41409699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com