问题
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