C# Xamarin-Entity Framework-SqLite-GetItemsAsync:无法打开数据库文件

C# Xamarin-Entity Framework-SqLite-GetItemsAsync:无法打开数据库文件,c#,sqlite,xamarin,xamarin.forms,entity-framework-core,C#,Sqlite,Xamarin,Xamarin.forms,Entity Framework Core,在Visual studio 2017中,我创建了一个跨平台移动应用程序(Xamarin.Forms) NetStandard2.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 我首先用实体框架将代码迁移到Sqlite。所有表都已成

在Visual studio 2017中,我创建了一个跨平台移动应用程序(Xamarin.Forms)

  • NetStandard2.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
我首先用实体框架将代码迁移到Sqlite。所有表都已成功创建。该数据库已植入种子

当我尝试获取ItemsViewModel(请参见下面的代码)时,我在-->List item list1=wait db.Person.toListSync()行上得到以下异常(20秒后)

Microsoft.Data.Sqlite.SqliteException(0x80004005):Sqlite错误14: “无法打开数据库文件”。在 Microsoft.Data.Sqlite.SqliteException.ThroweExceptionForRC(Int32 rc, 位于Microsoft.Data.Sqlite.SqliteConnection.Open()的 System.Data.Common.DbConnection.OpenAsync(CancellationToken 取消令牌)

奇怪的是,我的测试方法TestSqLiteDataStoreAsync(请参见下面的代码)正确地返回了预期的项目列表,而没有导致错误

另外,获取错误消息需要20秒,这表明它能够找到数据库。当您有错误的数据库名称/路径时,错误会立即弹出

下面是相关代码。如果你还需要什么,请告诉我。 还欢迎提供有关如何继续调试的任何帮助。或者有谁有一个基本的工作UWP代码的例子,我可以比较我的?我添加了一个 使用所需的数据库调用“temp”。如果有时间尝试重现错误:) Thx

[XamlCompilation(XamlCompilationOptions.Compile)]
公共部分类项目页面:ContentPage
{
ItemsViewModel视图模型;
公共项目
{
初始化组件();
//1代码从这里开始
BindingContext=viewModel=newitemsviewmodel();
}
已选择异步(对象发送方,SelectedItemChangedEventArgs args)
{
var item=args.SelectedItem作为项目;
如果(项==null)
返回;
等待Navigation.PushAsync(newitemDetailPage(newitemDetailViewModel(item));
ItemsListView.SelectedItem=null;
}
已单击异步无效添加项(对象发送方,事件参数e)
{
wait Navigation.PushModalAsync(new NavigationPage(new NewItemPage());
}
//添加“async”并不能解决问题
受保护的异步重写void OnAppearing()
{
base.OnAppearing();
if(viewModel.Items.Count==0)
//2代码在此继续
viewModel.LoadItemsCommand.Execute(null);
}
}
公共类ItemsViewModel:BaseViewModel
{
公共ObservableCollection项{get;set;}
公共命令LoadItemsCommand{get;set;}
public ItemsViewModel()
{
Title=“浏览”;
Items=新的ObservableCollection();
//3代码在此继续
LoadItemsCommand=new命令(async()=>await ExecuteLoadItemsCommand());
订阅(此“AddItem”,异步(obj,item)=>
{
var newItem=作为项目的项目;
项目。添加(新项目);
等待DataStore.AddItemAsync(newItem);
});
}
//我的测试方法
公共异步任务TestSqLiteDataStoreAsync()
{
SqLiteDataStore SqLiteDataStore=新SqLiteDataStore();
返回wait-SqLiteDataStore.GetItemsAsync(false);
}
异步任务ExecuteLoadItemsCommand()
{
如果(忙)
返回;
IsBusy=true;
尝试
{
Items.Clear();
//4代码在此继续
var items=await DataStore.GetItemsAsync(true);
foreach(项目中的var项目)
{
项目。添加(项目);
}
}
捕获(例外情况除外)
{
Debug.WriteLine(ex);
}
最后
{
IsBusy=false;
}
}
}
公共类SqLiteDataStore:IDataStore
{
公共字符串dbFolder=System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
公共字符串fileName=“TestSqLite.db”;
公共SqLiteDataStore(){}
公共异步任务GetItemsAsync(bool forceRefresh=false)
{
尝试
{
使用(var db=new Models.MyContext(Path.Combine(dbFolder,fileName)))
{
List list1=新列表();
List list2=新列表();
//我在这里得到了错误
list1=await db.Person.toListSync();
foreach(列表1中的人员)
{
项目=新项目(人);
清单2.添加(项目);
}
返回列表2;
}
}
捕获(例外)
{
投掷;
}
}
公共异步任务AddItemAsync(项)
{
抛出新的NotImplementedException();
}
公共任务更新同步(项目)
{
抛出新的NotImplementedException();
}
公共任务DeleteItemAsync(字符串id)
{
抛出新的NotImplementedException();
}
公共任务GetItemAsync(字符串id)
{
抛出新的NotImplementedException();
}
}
根据获取

“无法打开数据库文件”

错误-可能是将代码指向不存在的文件


“未找到表”错误意味着它找到了数据库,但没有找到您要查找的表。另一方面,“无法打开数据库文件”意味着它甚至找不到数据库,甚至懒得寻找表。当您得到“找不到表”时,您离它正常工作更近了。

正如我们前面提到的,只需将
环境.SpecialFolder.Personal
替换为
环境.SpecialFolder.LocalApplicationData[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();
    }
}
[3/10/2019 4:26:28 PM Informational] [xUnit.net 00:00:00.02] xUnit.net VSTest Adapter v2.4.0 (64-bit .NET Core 4.6.27129.04)
[3/10/2019 4:26:31 PM Informational] [xUnit.net 00:00:03.41]   Discovering: XUnitTestProject1
[3/10/2019 4:26:31 PM Informational] [xUnit.net 00:00:03.61]   Discovered:  XUnitTestProject1
[3/10/2019 4:26:31 PM Informational] ========== Discover test finished: 1 found (0:00:11.5651246) ==========
[3/10/2019 4:26:31 PM Informational] ------ Run test started ------
[3/10/2019 4:26:32 PM Informational] [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.0 (64-bit .NET Core 4.6.27129.04)
[3/10/2019 4:26:33 PM Informational] [xUnit.net 00:00:00.63]   Discovering: XUnitTestProject1
[3/10/2019 4:26:33 PM Informational] [xUnit.net 00:00:00.70]   Discovered:  XUnitTestProject1
[3/10/2019 4:26:33 PM Informational] [xUnit.net 00:00:00.70]   Starting:    XUnitTestProject1
[3/10/2019 4:26:35 PM Informational] [xUnit.net 00:00:02.60]   Finished:    XUnitTestProject1
[3/10/2019 4:26:35 PM Informational] ========== Run test finished: 1 run (0:00:03.9952011) ==========
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)
C:\Users\SomeUser\AppData\Local\Packages\0eea1ae6-65c3-42e9-9a50-869730e52f63_2ft3g98yvwh70\LocalState