How can I query Sqlite in Xamarin using Entity Framework?

巧了我就是萌 提交于 2020-01-06 06:55:10

问题


I'm in a Xamarin.Forms project (C#) using Sqlite and EF plug-in (Microsoft.Enttityframeworkcore.sqlite). What happens depends:

Scenario 1: I use "Database.EnsureDeletedAsync"

  • I can put data into DB
  • within the same "using" statement and "dbContext" object, I can retrieve the data using LINQ query no errors.

Scenario 2: I do not use "Database.EnsureDeletedAsync"

  • the database already exists
  • I can add data to it
  • within the same "using" statement and "dbContext" object, any attempt to retrieve the data using LINQ query (I've tried multiple ways), results in error (System.NullReferenceException: Object reference not set to an instance of an object).

In BOTH scenarios, I am able to ADB pull the db from the Android emulator and verify

1) the db exists and 2) my data are going into it.

FYI - the DbPath is verified to be correct (again, I can pull the DB and see data in it).

// POCO class

public class Participant
{
        [Key]
        public int Id { get; set; }
        public string Fname { get; set; }
}


// DB Context

public class DatabaseContext : DbContext
{
        string _dbPath;

        public DbSet<Participant> Participants { get; set; }

        public DatabaseContext(string dbPath)
        {
            _dbPath = dbPath;

            //Database.EnsureDeletedAsync();
            //Database.EnsureCreatedAsync();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename={_dbPath}");
        }
}


// Main page code-behind

InitializeComponent ();

// Create Database & Tables
using (var db = new DatabaseContext(App.DbPath))
{
    // Insert Data
    db.Add(new Participant() { Fname = "time: " + DateTime.Now.ToString() });
    db.SaveChanges();

    // Retrieve Data
    // Next two lines receive error in scenario 2
    var result2 = db.Participants.Where(xyz => xyz.Id == 1).ToList();
    IEnumerable<Participant> p = db.Participants.ToList();
}

回答1:


I add db.Database.EnsureCreated(); before you update data:

public MainPage()
{
    InitializeComponent();

    //iOS
    var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library", "iOSTest.db");

    // Android
    var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "AndroidTest.db");



    // Create Database & Tables
    using (var db = new DatabaseContext(dbPath))
    {

        db.Database.EnsureCreated();

        // Insert Data
        db.Add(new Participant() { Fname = "time: " + DateTime.Now.ToString() });
        db.SaveChanges();

        // Retrieve Data
        // Next two lines receive error in scenario 2
        var result2 = db.Participants.Where(xyz => xyz.Id == 1).ToList();
        IEnumerable<Participant> p = db.Participants.ToList();
    }
}

And DB Context:

  // DB Context

    public class DatabaseContext : DbContext
    {
        string _dbPath;

        public DbSet<Participant> Participants { get; set; }

        public DatabaseContext(string dbPath)
        {
            _dbPath = dbPath;

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename={_dbPath}");
        }
    }

1.You can try to change the DB name in your project to check if there is any wrong data in the old db. 2.Problems may caused by the asynchronous method.




回答2:


Problem solved! It turned out to be the dbContext and how/where that was defined vs. where it was attempted to be used. Code has been restructured to ensure not to lose the context scope before performing reads and writes.



来源:https://stackoverflow.com/questions/55655132/how-can-i-query-sqlite-in-xamarin-using-entity-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!