Xamarin - Entity Framework - SqLite : unable to open database file
In Visual studio 2017, I created a Cross-Platform Mobile App (Xamarin.Forms)
NETStandard 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
I did a code first migration to Sqlite with Entity Framework. All tables are created successfully. The database was seeded.
When I try to get the ItemsViewModel (see code below), I get the following exception (after 20 seconds) on the line --> List item list1 = await db.Person.ToListAsync();
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 14: 'unable to open database file'. at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db) at Microsoft.Data.Sqlite.SqliteConnection.Open() at System.Data.Common.DbConnection.OpenAsync(CancellationToken cancellationToken)
Strangely enough my method TestSqLiteDataStoreAsync (see code below) correctly returns the expected list of items.
Below you will find the relevant code. If you need anything more, let me know.
[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
{
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();
}
}