如何在LINQPad中使用Akavache?

4
根据Akavache的平台特定说明:

.NET 4.5桌面(WPF)-您必须将应用程序标记为x86,否则您将收到有关SQLitePCL_Raw未正确加载的奇怪运行时错误。

现在我只是想在LINQPad中使用简单的代码测试Akavache,该代码是根据Akavache Github页面上的示例代码建模的。
async void Main()
{
    BlobCache.ApplicationName = "JonTestApp1";
    var dt = DateTime.Now;
    await BlobCache.UserAccount.InsertObject("Test1", dt);
    var toaster = await BlobCache.UserAccount.GetObject<DateTime>("Test1");
    toaster.Dump();
}

预料之中的情况发生了。

我该如何在LINQPad中将我的应用程序构建目标标记为x86?使用v. 4.53.16,不是AnyCPU版本,只是普通的beta版。我已经在设置和谷歌中到处查找,但找不到任何东西。

谢谢

* 更新1 *

尝试@Joe Albahari的建议。IntPtr.Size确实是4。这是我在第一个await行上收到的异常:


System.TypeInitializationException: The type initializer for 'NativeMethods' threw an exception. ---> System.Exception: sqlite3.dll was not loaded.
   at SQLitePCL.SQLite3Provider.NativeMethods..cctor()
   --- End of inner exception stack trace ---
   at SQLitePCL.SQLite3Provider.NativeMethods.sqlite3_open_v2(Byte[] filename, IntPtr& db, Int32 flags, Byte[] vfs)
   at SQLitePCL.SQLite3Provider.SQLitePCL.ISQLite3Provider.sqlite3_open_v2(String filename, IntPtr& db, Int32 flags, String vfs)
   at Akavache.Sqlite3.Internal.SQLiteConnection..ctor(String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks)
   at Akavache.Sqlite3.Internal.SQLiteConnection..ctor(String databasePath, Boolean storeDateTimeAsTicks)
   at Akavache.Sqlite3.SQLitePersistentBlobCache..ctor(String databaseFile, IScheduler scheduler)
   at Akavache.Sqlite3.Registrations.c__DisplayClass6.b__2()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at Akavache.Sqlite3.Registrations.c__DisplayClass6.b__3()
   at Splat.ModernDependencyResolver.GetService(Type serviceType, String contract) in z:\code\paulcbetts\splat\Splat\ServiceLocation.cs:line 223
   at Splat.DependencyResolverMixins.GetService[T](IDependencyResolver This, String contract) in z:\code\paulcbetts\splat\Splat\ServiceLocation.cs:line 138
   at Akavache.BlobCache.get_UserAccount()
   at UserQuery.d__0.MoveNext() in c:\Users\jcomtois\AppData\Local\Temp\LINQPad\_qizvxzkh\query_rjuuom.cs:line 45

自从我通过LINQPad的NuGet安装了Akavache后,我不得不搜索一下sqlite3.dll的位置。我在Akavache NuGet包中找到了大约15个不同版本的slqlite3.dll(在我的AppData/Local/LINQPad/Nuget...文件夹中),供各种构建使用。我先尝试将x86文件夹中的一个复制到LINQPad目录中,但出现了相同的错误。然后我尝试将每个其他版本的sqlite3.dll复制到LINQPad文件夹中,但仍然出现相同的结果。
由于无法在这台机器上安装Visual Studio,因此我希望有一种方法可以使它与LINQPad一起使用。
3个回答

2

在被这个问题困扰了很长一段时间后,我查看了sqlite3_raw依赖项并找到了以下内容:

private static bool TryLoadFromDirectory(string dllName, string baseDirectory)
{
    /* snip */

    var architecture = IntPtr.Size == 4 ? "x86" : "x64";
    var dllPath = System.IO.Path.Combine(baseDirectory, architecture, dllName);
    if (!System.IO.File.Exists(dllPath))
    {
        return false;
    }

   /* snip - loads the dll */
}

当我将sqlite3.dll移动到"{linqpad}\x86\sqlite3.dll"时,它就能正常工作了。


你的回答让我找到了正确的方向来解决问题。显然,我遇到了比你更多的困难,所以我添加了一个详细的解决方案。感谢你的帮助! - Jon Comtois
这似乎不再起作用了,在做了一些事情之后,我现在遇到了一个“无法加载 DLL 'e_sqlite3'”的错误。 - Rhys Bevilaqua

1

@rdavisau的答案让我找到了正确的方向来解决这个问题。他的解决方案对我来说并不起作用。本回答使用的Akavache 4.1.0和LINQPad 4.55.03。

帮助我的源代码在这里

一旦我看到TryLoadFromDirectory被调用时,它的位置是new Uri(AppDomain.CurrentDomain.BaseDirectory).LocalPath)以查找sqlite3.dll,我就可以通过在那行代码上调用.Dump()来查看LINQPad中的位置。

目前,对我来说,它是C:\ProgramData\LINQPad\Updates40\455\。这有点不幸,因为每次LINQPad自动更新时,它都会进入不同的目录。

因此,我在找到的那个目录中创建了一个x86目录,并尝试从NuGet包中将sqlite3.dll放入其中。 我不得不去LINQPad的NuGet缓存中查找它。 我确定对我来说正确的是在这里找到的:C:\Users\jcomtois\AppData\Local\LINQPad\NuGet\akavache.sqlite3\SQLitePCL.raw_basic.0.7.0\build\native\sqlite3_dynamic\winxp\x86\sqlite3.dll

所以现在我认为我有适用于我的测试LINQPad程序的正确.dll文件。 我运行它,然后收到提示:The Program can't start because MSVCR110.dll is missing from your computer. Try reinstalling the program to fix this problem. 烦死了。请记住这台机器没有安装Visual Studio。 我去here下载并安装了可再发行组件。

我再次运行我的测试代码(在执行“取消所有线程并重置”后)。 成功!

一旦这样做了,我尝试将带有正确的sqlite3.dllx86文件夹放在LINQPad安装目录中,但是没有成功。我认为这就是@rdavisau在他的答案中所指的,因为不清楚。在LINQPad中运行Akavache有点麻烦,我希望它更容易,但是它确实是可能的。

有趣的是,当我测试BaseDirectory时,我得到了我的LINQPad安装目录。实际上,我在两个盒子上尝试了这个修复方法,所以我认为对于每个人来说都是一样的。反思一下,我总是使用“无安装程序”的LINQPad版本 - 这可能与此有关。 - rdavisau

0

X86版本的LINQPad总是在32位进程中运行您的查询。

您可以通过运行以下查询来验证:

IntPtr.Size

如果返回值为4,则表示您正在运行32位进程。
您提到您的库使用SQLite。如果是这样,问题可能是CLR无法解析其本地DLL。尝试将SQLite的本地DLL复制到LINQPad文件夹中(您可以创建一个专门用于此目的的带有LINQPad.exe副本的特殊文件夹)。

我在我的问题中添加了一些更新的信息。我正在32位进程中。然而,要么我没有将正确的sqlite DLL复制到我的LINQPad文件夹中,要么那不是问题所在。到目前为止还没有运气。 - Jon Comtois

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