如何在Blazor WebAssembly中使用SQLite?

vcudknz3  于 2022-11-14  发布在  SQLite
关注(0)|答案(3)|浏览(316)

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

06odsfpq

06odsfpq1#

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

ubby3x7f

ubby3x7f2#

.Net 6开始,现在可以将SQLiteBlazor Web Assembly一起使用。
以下是步骤,
1.添加对以下Nuget包的引用。A.Microsoft.EntityFrameworkCore.Sqlite b.SQLitePCLRaw.bundle_e_sqlite3-截至发布此答案时,目前正在预览中。此包是为了避免NativeFileReferencee_sqlite3.o
1.在.csproj中添加以下内容,以避免弹出不需要的警告。

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EmccExtraLDFlags>-s WARN_ON_UNDEFINED_SYMBOLS=0</EmccExtraLDFlags>

1.在Program.cs中添加以下代码。这是避免运行时异常所必需的-Could not find method 'AddYears' on type 'System.DateOnly'

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);
}

1.我在内存存储中使用了SQLite。以下是代码示例。

数据库模型:

public class Name
{
    public int Id { get; set; }
    public string FullName { get; set; }
}

数据库上下文:

public class TestDbCOntext : DbContext
{
    public DbSet<Name> Names { get; set; } = default!;

    public TestDbCOntext(DbContextOptions<TestDbCOntext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Name>().ToTable("Names");
        modelBuilder.Entity<Name>().HasIndex(x => x.FullName);
        modelBuilder.Entity<Name>().Property(x => x.FullName).UseCollation("nocase");
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.LogTo(Console.WriteLine, LogLevel.Warning)
                .EnableDetailedErrors()
                .EnableSensitiveDataLogging(true);
    }
}

页面/组件:

<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();
}
}

1.为了持久化,您可以在浏览器中使用IndexedDB并同步保存到您的服务器中。
示例工作演示可以在我的Github Repo - BlazorWasmEfCore中找到
Live Demo
有关完整的历史记录,请参阅github issue
Steve Sanderson Video Reference

截图:

注意事项:

以下详细信息摘自下面的stackoverflow answer
编程的一个好规则就是保持简单。因此,如果Linq to Object满足了您的应用程序的需求,那么使用SQLite将其复杂化似乎是错误的。
然而,在视频中,Steve S.确实提出了适合使用SQLite的需求参数--应用程序需要处理:

  • 大量数据
  • 在客户端
  • 离线
  • 迅速
  • 这里使用SQLite不是为了在客户端应用程序内存之外持久化。

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

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

8ehkhllq3#

您的Blazor WebAssembly C#代码仍然在浏览器的沙箱中运行,这意味着它不允许打开本地驱动器上的文件。
Blazor WebAssembly拥有与任何常规网站相同的计算机访问权限。
即使有人将SQLite移植到WebAssembly,您也无法打开数据库文件。
对于客户端计算机上的存储,您被限制为本地存储,它被限制为5 MB(可能因浏览器品牌而异),并且只能包含字符串。但这不是一个可靠的选择,因为当用户清除缓存、浏览器历史记录等时,数据将被删除。
您唯一的选择是将数据存储在服务器上。

相关问题