简体   繁体   中英

How can I query Sqlite in Xamarin using Entity Framework?

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();
}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM