.NET 6 Blazor Wasm使用Sqlite报e_sqlite3缺失错误求可用实现示例
解决.NET 6 Blazor WebAssembly集成SQLite时e_sqlite3缺失异常的实现方案
该异常的核心原因是Blazor WASM运行在浏览器沙箱环境中,无法直接加载传统桌面端的e_sqlite3原生动态库,必须使用通过Emscripten编译为WASM适配格式的sqlite3.o静态库完成链接才能正常运行。以下是可正常运行的完整实现步骤:
前置依赖
- 已安装.NET 6 SDK,并且安装对应版本的WASM工具链,安装命令:
dotnet workload install wasm-tools - 已通过Emscripten(版本需匹配.NET 6要求的2.0.23)编译出sqlite3.o静态库,编译时需添加参数
-s STANDALONE_WASM=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0保证兼容性
项目配置流程
- 在Blazor WASM项目根目录新建
NativeReferences文件夹,将编译好的sqlite3.o文件放入该目录 - 编辑项目.csproj文件,添加如下配置:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <!-- 原有配置保留,新增以下内容 --> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <WasmBuildNative>true</WasmBuildNative> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> <ItemGroup> <NativeReference Include="NativeReferences\sqlite3.o" /> <WasmExtraEmFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> <!-- 仅安装不带原生依赖的Sqlite核心包 --> <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.27" /> </ItemGroup> </Project>
- 添加WASM原生SQLite绑定初始化类,代码如下:
using System.Runtime.InteropServices; using Microsoft.Data.Sqlite; public static class WasmSqliteBinder { [DllImport("__Internal")] private static extern IntPtr sqlite3_libversion(); public static void Initialize() { // 验证原生库绑定是否正常 var versionPtr = sqlite3_libversion(); string sqliteVersion = Marshal.PtrToStringUTF8(versionPtr); Console.WriteLine($"SQLite原生库加载成功,版本:{sqliteVersion}"); // 配置Sqlite连接默认参数 SqliteConnection.DefaultFlags = SqliteOpenFlags.ReadWrite | SqliteOpenFlags.Create | SqliteOpenFlags.SharedCache; } }
- 在Program.cs入口处调用初始化方法:
var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); // 初始化SQLite绑定 WasmSqliteBinder.Initialize(); await builder.Build().RunAsync();
功能验证测试代码
可以在任意页面组件中添加如下代码验证功能是否正常:
protected override async Task OnInitializedAsync() { // 浏览器沙箱不支持本地磁盘持久化,示例使用内存模式,需要持久化可搭配虚拟文件系统实现 const string connectionString = "Data Source=demo.db;Mode=Memory;Cache=Shared"; using var connection = new SqliteConnection(connectionString); await connection.OpenAsync(); // 创建测试表 var createTableCmd = connection.CreateCommand(); createTableCmd.CommandText = "CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY AUTOINCREMENT, UserName TEXT NOT NULL)"; await createTableCmd.ExecuteNonQueryAsync(); // 插入测试数据 var insertCmd = connection.CreateCommand(); insertCmd.CommandText = "INSERT INTO Users (UserName) VALUES ('测试用户')"; await insertCmd.ExecuteNonQueryAsync(); // 查询测试 var queryCmd = connection.CreateCommand(); queryCmd.CommandText = "SELECT Id, UserName FROM Users WHERE Id = last_insert_rowid()"; using var reader = await queryCmd.ExecuteReaderAsync(); if (await reader.ReadAsync()) { Console.WriteLine($"查询结果:Id={reader.GetInt32(0)}, UserName={reader.GetString(1)}"); } await base.OnInitializedAsync(); }
注意事项
- 不要安装默认的
Microsoft.Data.Sqlite包,该包会携带不兼容WASM的原生依赖,仅安装Microsoft.Data.Sqlite.Core即可 - 如果需要持久化存储数据,需自行实现适配浏览器的虚拟文件系统,将SQLite的数据写入IndexedDB等浏览器存储介质中
- 编译sqlite3.o的Emscripten版本必须和.NET 6 WASM工具链要求的版本一致,否则会出现链接错误
内容的提问来源于stack exchange,提问作者Abdulqadir_WDDN
相关产品推荐
相关产品推荐

