如何在 Blazor WebAssembly 中使用 SQLite?

JAL*_*JAL 11 c# sqlite blazor blazor-webassembly

对于 Blazor WebAssembly,我提出了使用 SQLite 的想法。这个问题提到这是不可能的。是否可以在 Blazor WebAssembly 中使用 SQLite?如果可以,如何使用?

小智 13

从 .NET 6 开始,您可以在 Blazor WebAssembly 中使用包含本机依赖项,​​其中一个例子就是 SQLite。请参阅此处的示例代码:https://github.com/SteveSandersonMS/BlazeOrbital/blob/6b5f7892afbdc96871c974eb2d30454df4febb2c/BlazeOrbital/ManufacturingHub/Properties/NativeMethods.cs#L6

  • 您可以在这里看到这一点:[Steven Sanderson on Blazor WebAssemby @ .NETConf21](https://www.youtube.com/watch?v=kesUNeBZ1Os)(观看时间约 30 分钟) (3认同)

fin*_*s10 9

首先.Net 6,现在可以使用SQLitewith Blazor Web Assembly

以下是步骤,

  1. 添加对以下 Nuget 包的引用。A。Microsoft.EntityFrameworkCore.Sqlite b. SQLitePCLRaw.bundle_e_sqlite3- 截至发布此答案时目前处于预览状态。这个包是为了NativeFileReference避免e_sqlite3.o.
  2. 添加以下内容.csproj以避免弹出不需要的警告。
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EmccExtraLDFlags>-s WARN_ON_UNDEFINED_SYMBOLS=0</EmccExtraLDFlags>
Run Code Online (Sandbox Code Playgroud)
  1. 在 中添加以下代码Program.cs。这是避免运行时异常所必需的 -Could not find method 'AddYears' on type 'System.DateOnly'
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EmccExtraLDFlags>-s WARN_ON_UNDEFINED_SYMBOLS=0</EmccExtraLDFlags>
Run Code Online (Sandbox Code Playgroud)
  1. 我正在使用 sqlite 内存存储。这是代码示例。

数据库模型:

public partial class Program 
{
    /// <summary>
    /// FIXME: This is required for EF Core 6.0 as it is not compatible with trimming.
    /// </summary>
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
    private static Type _keepDateOnly = typeof(DateOnly);
}
Run Code Online (Sandbox Code Playgroud)

数据库上下文:

public class Name
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

页面/组件:

<button @onclick="RunEfCore">Run Ef Core</button>

@code {
private async Task RunEfCore()
{
    var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" };
    var connection = new SqliteConnection(connectionStringBuilder.ToString());

    var options = new DbContextOptionsBuilder<TestDbCOntext>()
        .UseSqlite(connection)
        .Options;

    using var db = new TestDbCOntext(options);
    db.Database.OpenConnection();
    await db.Database.EnsureCreatedAsync();
    var nextId = db.Names!.Count() + 1;
    db.Names.Add(new Name { Id = nextId, FullName = "Abdul Rahman" });
    await db.SaveChangesAsync();

    Console.WriteLine();
    await foreach (var name in db.Names.AsAsyncEnumerable())
    {
        Console.WriteLine(name.FullName);
    }
    db.Database.CloseConnection();
}
}
Run Code Online (Sandbox Code Playgroud)
  1. 为了持久化,您可以使用IndexedDB浏览器同步来保存在您的服务器中。

示例工作演示可以在我的 Github 存储库中找到- BlazorWasmEfCore

现场演示

请参阅github 问题以获取完整的历史记录。

史蒂夫·桑德森视频参考

截屏: 演示

需要考虑的要点:

以下详细信息取自以下stackoverflow 答案

一个好的编程规则是 KISS - 保持简单。因此,如果 Linq to Objects 满足了应用程序的要求,那么使用 SQLite 使其复杂化似乎是错误的做法。

然而,在视频中 Steve S. 确实提出了适合使用 SQLite 的要求参数 - 应用程序需要处理:

  • 很多数据
  • 在客户端
  • 离线
  • 迅速地
  • 这里使用 SQLite 并不是为了持久保存到客户端应用程序内存之外。

因此,关于使用 SQLite 的 Blazor 应用程序的优势的问题的答案很简单:

  • 如果一个应用程序需要内存关系数据库的功能,但试图避免使用它,那么它要么在实现中重新发明轮子,要么缺少必要的功能。
  • 如果应用程序不需要内存数据库的功能但正在使用内存数据库,则会引入不必要的复杂性(成本)。


小智 1

您的 Blazor WebAssembly C# 代码仍然在浏览器的沙箱中运行,这意味着不允许打开本地驱动器上的文件。

Blazor WebAssembly 具有与任何常规网站相同的计算机访问权限。

即使有人将 SQLite 移植到 WebAssembly,您也无法打开数据库文件。

对于客户端计算机上的存储,您仅限于本地存储,其大小限制为 5 MB(每个浏览器品牌可能有所不同),并且只能包含字符串。但这不是一个可靠的选择,因为当用户清除缓存、浏览器历史记录等时,数据将被删除。

您唯一的选择是将数据存储在服务器上。