【发布时间】:2019-06-02 00:09:18
【问题描述】:
在 Visual Studio 2017 中,我创建了一个跨平台移动应用 (Xamarin.Forms)
- NET 标准 2.0
- Microsoft.Data.Sqlite.Core 2.2.0
- Microsoft.EntityFrameworkCore 2.2.0
- Microsoft.EntityFrameworkCore.Sqlite 2.2.0
- Microsoft.EntityFrameworkCore.Tools 2.2.0
我在the advice of Mark Smith 之后使用实体框架进行了代码第一次迁移到 Sqlite。所有表均已成功创建。数据库已播种。
当我尝试获取 ItemsViewModel(请参见下面的代码)时,我在该行上得到以下异常(20 秒后) --> List item list1 = await db.Person.ToListAsync();
Microsoft.Data.Sqlite.SqliteException (0x80004005):SQLite 错误 14: '无法打开数据库文件'。在 Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db) 在 Microsoft.Data.Sqlite.SqliteConnection.Open() 在 System.Data.Common.DbConnection.OpenAsync(CancellationToken 取消令牌)
奇怪的是,我的测试方法 TestSqLiteDataStoreAsync(参见下面的代码)正确地返回了预期的项目列表而不会导致错误。
此外,获取错误消息需要 20 秒这一事实表明它能够找到数据库。当您有错误的数据库名称/路径时,错误会立即弹出。
您可以在下面找到相关代码。如果您还需要什么,请告诉我。 也欢迎任何有关如何继续调试的帮助。或者有没有人可以比较我的基本工作 UWP 代码示例?我添加了一个 solution on Github 使用所需的数据库调用“temp”。如果有人可能有时间尝试重现错误:) 谢谢。
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ItemsPage : ContentPage
{
ItemsViewModel viewModel;
public ItemsPage()
{
InitializeComponent();
//1 code starts here
BindingContext = viewModel = new ItemsViewModel();
}
async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
var item = args.SelectedItem as Item;
if (item == null)
return;
await Navigation.PushAsync(new ItemDetailPage(new ItemDetailViewModel(item)));
ItemsListView.SelectedItem = null;
}
async void AddItem_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new NavigationPage(new NewItemPage()));
}
//adding 'async' did not solve the problem
protected async override void OnAppearing()
{
base.OnAppearing();
if (viewModel.Items.Count == 0)
//2 code continues here
viewModel.LoadItemsCommand.Execute(null);
}
}
public class ItemsViewModel : BaseViewModel
{
public ObservableCollection<Item> Items { get; set; }
public Command LoadItemsCommand { get; set; }
public ItemsViewModel()
{
Title = "Browse";
Items = new ObservableCollection<Item>();
//3 code continues here
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
{
var newItem = item as Item;
Items.Add(newItem);
await DataStore.AddItemAsync(newItem);
});
}
//My test method
public async Task<List<Item>> TestSqLiteDataStoreAsync()
{
SqLiteDataStore SqLiteDataStore = new SqLiteDataStore();
return await SqLiteDataStore.GetItemsAsync(false);
}
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
Items.Clear();
//4 code continues here
var items = await DataStore.GetItemsAsync(true);
foreach (var item in items)
{
Items.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
public class SqLiteDataStore : IDataStore<Item>
{
public string dbFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
public string fileName = "TestSqLite.db";
public SqLiteDataStore() { }
public async Task<List<Item>> GetItemsAsync(bool forceRefresh = false)
{
try
{
using (var db = new Models.MyContext(Path.Combine(dbFolder, fileName)))
{
List<Person> list1 = new List<Person>();
List<Item> list2 = new List<Item>();
//5 I get the error here
list1 = await db.Person.ToListAsync();
foreach (Person person in list1)
{
Item item = new Item(person);
list2.Add(item);
}
return list2;
}
}
catch (Exception)
{
throw;
}
}
public async Task<bool> AddItemAsync(Item item)
{
throw new NotImplementedException();
}
public Task<bool> UpdateItemAsync(Item item)
{
throw new NotImplementedException();
}
public Task<bool> DeleteItemAsync(string id)
{
throw new NotImplementedException();
}
public Task<Item> GetItemAsync(string id)
{
throw new NotImplementedException();
}
}
【问题讨论】:
-
将
Environment.SpecialFolder.Personal替换为Environment.SpecialFolder.LocalApplicationData看看是否有帮助。
标签: c# sqlite xamarin xamarin.forms entity-framework-core