UWP应用无法打开本地SQLite数据库:Microsoft.Data.Sqlite.Core 8.0.0异常
解决UWP中使用Microsoft.Data.Sqlite.Core时的TypeInitializationException异常
异常原因
- 缺少SQLite原生依赖包:仅安装
Microsoft.Data.Sqlite.Core不足以运行SQLite,这个包仅包含核心逻辑,不包含SQLite的原生运行库和初始化组件,导致底层驱动无法被找到。 - 未执行SQLite初始化:异常提示明确要求调用
SQLitePCL.Batteries.Init(),该方法用于注册SQLite的原生提供者,未调用会直接引发类型初始化失败。 - 代码异步语法错误:原
DataAccessService构造函数使用await但未标记为async,属于语法错误,数据库路径初始化逻辑无法正确执行。
解决步骤
1. 安装必要的NuGet包
在NuGet包管理器中安装SQLitePCLRaw.bundle_e_sqlite3包,该包包含SQLite原生运行库和初始化工具,会自动处理所有依赖关系。
2. 初始化SQLite
在应用启动时执行初始化,确保在创建SqliteConnection之前完成。修改App.xaml.cs的OnLaunched方法:
protected override void OnLaunched(LaunchActivatedEventArgs e) { // 初始化SQLite原生提供者 SQLitePCL.Batteries.Init(); Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); rootFrame.NavigationFailed += OnNavigationFailed; Window.Current.Content = rootFrame; } if (e.PrelaunchActivated == false) { if (rootFrame.Content == null) { rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate(); } }
3. 修正数据访问类的异步逻辑
构造函数无法直接标记为async,改为异步初始化方法,同时修复连接创建时的using错误(原代码中using会提前释放连接,导致返回无效实例):
public class DataAccessService { public string pathToDatabase = string.Empty; private static DataAccessService _instance; private static readonly object _lockObj = new object(); private DataAccessService() { } // 异步初始化数据库路径 public async Task InitializeAsync() { StorageFile storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync( "sqliteEula.db", CreationCollisionOption.OpenIfExists ); pathToDatabase = storageFile.Path; } public SqliteConnection GetNewConnection() { Debug.WriteLine($"Database: {pathToDatabase}"); try { var connection = new SqliteConnection($"Filename={pathToDatabase}"); connection.Open(); return connection; } catch (Exception ex) { Debug.WriteLine(ex.StackTrace); return null; } } // 异步获取单例实例 public static async Task<DataAccessService> GetInstanceAsync() { if (_instance == null) { lock (_lockObj) { _instance ??= new DataAccessService(); } await _instance.InitializeAsync(); } return _instance; } }
4. 修正主页面的调用逻辑
由于获取实例变为异步操作,需在主页面中异步初始化:
public sealed partial class MainPage : Page { private DataAccessService _dataAccessService; public MainPage() { this.InitializeComponent(); // 异步初始化数据服务,不阻塞UI线程 _ = InitializeDataServiceAsync(); } private async Task InitializeDataServiceAsync() { _dataAccessService = await DataAccessService.GetInstanceAsync(); } private void DataAccess_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { if (_dataAccessService == null) return; SqliteConnection connection = _dataAccessService.GetNewConnection(); // 使用连接后记得手动关闭或用using包裹 using (connection) { // 执行数据库操作 } } }
内容的提问来源于stack exchange,提问作者Kenny Roy Elphej
相关产品推荐
相关产品推荐

