我有 Xamarin Forms 解决方案。我添加了 sqlite-net-pcl 作为所有项目的参考。它在 Android 上运行良好,但在 Windows 8.1 和 Windows Phone 8.1 上崩溃。我有一个 IOS 项目,但目前没有 OSX 来尝试。
我在Windows项目中使用它来访问数据库:
using System.IO;
using SQLite;
using Xamarin.Forms;
using HelloXamarin.Windows;
using Windows.Storage;
[assembly: Dependency(typeof(SQLiteDb))]
namespace HelloXamarin.Windows
{
public class SQLiteDb : ISQLiteDb
{
public SQLiteAsyncConnection GetConnection(string databaseName)
{
var documentsPath = ApplicationData.Current.LocalFolder.Path;
var path = Path.Combine(documentsPath, databaseName);
return new SQLiteAsyncConnection(path);
}
}
}
以下是我的参考资料:
尝试访问数据库时出现此异常:
“SQLite.SQLiteConnection”的类型初始值设定项引发异常。
无法加载DLL“e_sqlite3”:找不到指定的模块。 (HRESULT 异常:0x8007007E)
我不知道如何解决这个问题,请帮助我!
整个解决方案可以在 GitHub 上找到: https://github.com/apspot/HelloXamarin
对我来说,它是通过将 e_sqlite3 包添加到可执行项目
来工作的此时问题仍然是开放。因此,在他们提供一些可靠的修复之前,您可以使用此解决方案暂时解决问题。
添加一个辅助类
using System;
using System.Diagnostics;
using System.IO;
namespace SQLitePCL
{
public class NativeLibraryHack
{
public static bool Hacked { get; private set; }
public static bool DoHack()
{
if (Hacked) return true;
try
{
const string runtimeFolderName = "/runtimes";
var destinationPath = typeof(SQLitePCL.raw).Assembly.Location
.Replace("\\", "/");
var destinationLength = destinationPath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
var destinationDirectory = destinationPath.Substring(0, destinationLength) + runtimeFolderName;
var sourcePath = new Uri(typeof(SQLitePCL.raw).Assembly.CodeBase)
.AbsolutePath;
var sourceLength = sourcePath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
var sourceDirectory = sourcePath.Substring(0, sourceLength) + runtimeFolderName;
if (Directory.Exists(sourceDirectory))
CopyFilesRecursively(new DirectoryInfo(sourceDirectory), new DirectoryInfo(destinationDirectory));
}
catch (Exception ex)
{
//Ignore Exception
Debug.WriteLine(ex.Message);
return false;
}
return (Hacked = true);
}
private static void CopyFilesRecursively(
DirectoryInfo source,
DirectoryInfo target
)
{
foreach (var dir in source.GetDirectories())
CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
foreach (var file in source.GetFiles())
{
try
{
var destinationFile = Path.Combine(target.FullName, file.Name);
if (!File.Exists(destinationFile))
file.CopyTo(destinationFile);
}
catch (Exception ex)
{
//Ignore Exception
Debug.WriteLine(ex.Message);
}
}
}
}
}
并在数据库迁移脚本之前添加 hack,我正在使用 web api 2 所以我做了
RouteConfig.RegisterRoutes
NativeLibraryHack.DoHack();
using (KSDBContext db = new KSDBContext())
{
db.Database.Migrate();
}
尝试引用通用 Windows 平台应用程序的 Visual C++ 2015 运行时。这为我解决了。
我相信这个问题的根源是程序无法加载
e_sqlite3.dll
文件。我认为这里的所有问题都以某种方式通过移动文件或更新路径来解决这个问题,它们似乎都有效。
仅供参考,如果您包含
Microsoft.Data.Sqlite
,它应该下载传递包 sqlitepclraw.lib.e_sqlite3
,其中包含以下文件
%nuget packages%\sqlitepclraw.lib.e_sqlite3\%version%\runtimes\%platform%