如何在 LINQPad 中使用 Akavache?

How to use Akavache in LINQPad?

根据 Akavache 的平台特定说明:

.NET 4.5 Desktop (WPF) - You must mark your application as x86, or else you will get a strange runtime error about SQLitePCL_Raw not loading correctly.

现在,我只是尝试使用模仿 Akavache Github 页面上的示例代码的简单代码在 LINQPad 中测试 Akavache。

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 版本,只是正常的测试版。我在设置和 Google 中到处查看,但找不到任何东西。

谢谢

* 更新 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 包中(在我的 AppData/Local/LINQPad/Nuget... 中)发现了大约 15 个不同的 slqlite3.dll 用于各种构建。我尝试先将 x86 文件夹中的复制到 LINQPad 目录,但同样的错误。然后我尝试将其他 sqlite3.dll 中的每一个复制到 LINQPad 文件夹,但结果仍然相同。

我无法在这台机器上安装 Visual Studio,所以我希望有办法让它与 LINQPad 一起工作。

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

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

IntPtr.Size

如果此 returns 4,则您处于 32 位进程中。

您提到您的库使用 SQLite。如果是这样,问题可能是 CLR 无法解析其本机 DLL。尝试将 SQLite 的本机 DLL 复制到 LINQPad 文件夹中(您可以为此目的创建一个包含 LINQPad.exe 副本的特殊文件夹)。

在对这个基本上永远感到沮丧之后,我梳理了 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”,它就可以正常工作。

@rdavisau 的 让我走上了正确的轨道,最终弄清楚了这一点。他的解决方案对我不起作用。此答案中的 Akavache 4.1.0 和 LINQPad 4.55.03。

对我有帮助的源代码是here

一旦我看到 TryLoadFromDirectory 被调用并使用 new Uri(AppDomain.CurrentDomain.BaseDirectory).LocalPath) 作为查找 sqlite3.dll 的位置,我就能够通过调用 sqlite3.dll 查看该位置在 LINQPad 中的位置=13=]在那一行代码上。

目前对我来说,是C:\ProgramData\LINQPad\Updates405\。这有点不幸,因为每次 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 并下载并安装了可再发行组件。

我再次 运行 我的测试代码(在 "Cancel all threads and reset" 之后)。成功!

一旦成功,我尝试将 x86 文件夹与正确的 sqlite3.dll 放在 LINQPad 安装目录中,但这没有用。我认为那是@rdavisau 在他的回答中所指的,因为它不清楚。

对 LINQPad 中的 运行 Akavache 有点考验,我希望它更容易,但它 可能的。