Lan*_*nce -1 c# sqlite xamarin.forms uwp
尝试打开 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();
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
在 System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken CancellationToken) 在 System.Threading.Tasks.Task.Wait() 在 TheRandomizer.Services.SqliteDataStore..ctor() 在 TheRandomizer.ViewModels.BaseViewModel.get_DataStore()在TheRandomizer.ViewModels.GeneratorListViewModel.ExecuteLoadItemsCommand()
我已经在本地测试了您的代码,并看到该行为实际上正在发生,经过一些调试后,我认为我可能有两个原因:
首先,构造函数只有标志SQLiteOpenFlags.Create
。显然这不会给你任何其他权限,包括读/写。相反,您可以完全省略第二个参数:
_database = new SQLiteAsyncConnection(DBPath);
Run Code Online (Sandbox Code Playgroud)
或者包含显式ReadWrite
标志(我还包含了该FullMutex
标志,因为建议用于异步连接):
_database = new SQLiteAsyncConnection(
DBPath,
SQLiteOpenFlags.Create |
SQLiteOpenFlags.FullMutex |
SQLiteOpenFlags.ReadWrite );
Run Code Online (Sandbox Code Playgroud)
在数据库中创建GeneratorTable
表时出现第二个问题。SQLite 不知道如何存储该Version
属性,因为它是自定义GeneratorVersion
类型。因此,您可能必须将其分解为简单的属性或添加一个[Ignore]
属性。
我检查了您的源代码,发现您正在尝试将数据库存储在Environment.SpecialFolder.Personal
文件夹中。对于 UWP,这实际上解析为C:\Users\$Username$\Documents
,UWP 应用程序无权访问它,因为它在沙箱中运行并且无权访问。
相反,您必须使用应用程序的数据文件夹(您可能实际上打算这样做):
Path.Combine(ApplicationData.Current.LocalFolder.Path, FILE_NAME);
Run Code Online (Sandbox Code Playgroud)