尝试打开我的SQLite连接时出现异常“无法打开数据库文件:[路径](滥用)”。
我正在创建Xamarin.Forms应用程序,并在UWP中进行调试,这是我遇到异常的地方。
我的数据存储类的构造函数创建连接和表:
internal static string DBPath
{
get
{
const string FILE_NAME = "TheRandomizer.db3";
if (Device.RuntimePlatform == Device.Android)
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), FILE_NAME);
}
else
{
return Path.Combine(ApplicationData.Current.LocalFolder.Path, FILE_NAME);
}
}
}
public SqliteDataStore()
{
_database = new SQLiteAsyncConnection(DBPath, SQLiteOpenFlags.Create);
// Fails trying to perform this action:
_database.CreateTableAsync<GeneratorTable>().Wait();
_database.CreateTableAsync<TagTable>().Wait();
}
可以查看here on my GitHub的完整来源。
堆栈跟踪:
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, 的CancellationToken cancelToken() System.Threading.Tasks.Task.Wait()在 TheRandomizer.Services.SqliteDataStore..ctor()在 TheRandomizer.ViewModels.BaseViewModel.get_DataStore()在 TheRandomizer.ViewModels.GeneratorListViewModel.ExecuteLoadItemsCommand()
答案 0 :(得分:0)
我已经在本地测试了您的代码,并看到该行为实际上正在发生,并且在进行一些调试之后,我认为我可能有两个原因:
首先,构造函数只有SQLiteOpenFlags.Create
标志。显然,这不给您任何其他权限,包括读/写。相反,您可以完全省略第二个参数:
_database = new SQLiteAsyncConnection(DBPath);
或包含显式的ReadWrite
标志(由于建议用于异步连接,我还包含了FullMutex
标志):
_database = new SQLiteAsyncConnection(
DBPath,
SQLiteOpenFlags.Create |
SQLiteOpenFlags.FullMutex |
SQLiteOpenFlags.ReadWrite );
在数据库中创建GeneratorTable
表时发生第二个问题。 SQLite不知道如何存储Version
属性,因为它是自定义的GeneratorVersion
类型。因此,您可能必须将其分解为简单的属性或添加一个[Ignore]
属性。
我检查了您的源代码,发现您正在尝试将数据库存储在Environment.SpecialFolder.Personal
文件夹中。对于UWP,它实际上解析为C:\Users\$Username$\Documents
,由于UWP应用程序正在沙箱中运行,因此它无权访问。
相反,您必须使用应用程序的数据文件夹(您可能实际上打算这样做):
Path.Combine(ApplicationData.Current.LocalFolder.Path, FILE_NAME);