как правильно создать базу данных EF Core на устройстве Android / iOS с помощью Xamarin.Forms и EntityFrameworkCore?
Я столкнулся с проблемой EnsureCreated
vs Migrate
, и, поскольку я планирую изменить структуру базы данных в будущем, я хотел бы иметь возможность применить эти миграции к существующей базе данных , поэтому я выбрал подход Migrate
.
Однако, когда я вызываю метод Migrate
, кажется, что он не создает базу данных. Мне удалось заставить его работать, если я заранее скопирую предварительно сгенерированный файл базы данных на устройства, но это не то, что я хочу. Есть ли способ указать EF Core проверить, существует ли база данных, создать новую базу данных, если нет, а затем применить к ней ожидающие миграции?
Вот что я сделал на данный момент:
- Я создал стандартную библиотеку классов. net «Data», которая будет содержать все мои классы базы данных (контекст, модели и миграции).
- Я изменил TargetFramework проекта «Data» с
<TargetFramework>netstandard2.0</TargetFramework>
на <TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
, чтобы я мог запускать на нем команды PM C. - Я установил эти nuget пакеты в проект «Данные»:
- EntityFrameworkCore
- EntityFrameworkCore.Sqlite
- EntityFrameworkCore.Tools
- EntityFrameworkCore.Design
- Я создал класс контекста базы данных. Я сделал для него два конструктора. Значение по умолчанию будет использоваться только командами PM C для генерации миграций. Другой будет использоваться в производстве.
public class MyTestContext : DbContext
{
private string _databasePath;
public DbSet<Issue> Issues { get; set; }
[Obsolete("Don't use this for production. This is only for creating migrations.")]
public MyTestContext() : this("nothing.db")
{
}
public MyTestContext(string databasePath)
{
_databasePath = databasePath;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//I've also tried Filename={_databasePath} here, didn't work either
optionsBuilder.UseSqlite($"Data Source={_databasePath}");
}
}
Я создал класс тестовой модели, просто чтобы было с чем поиграть
public class Issue
{
public string Id { get; set; }
}
Я создал начальную миграцию, используя эту команду, которая успешно завершилась:
Add-Migration Migration001 -Context MyTestContext -Output Migrations
Я добавил вызов метода
Migrate
в App.xaml.cs моего проекта Xamarin.Forms, чтобы проверить, работает ли он.
public partial class App : Application{
//... other code
protected override async void OnStart()
{
base.OnStart();
using (var db = new MyTestContext(_dbPath))
{
try
{
db.Database.Migrate();
db.Issues.Add(new Issue
{
Id = "TestIssueId"
});
db.SaveChanges();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
}
//... other code
}
Переменная _dbPath
содержит это (на Android, где я его тестирую):
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "test.db");
После всего этого я получаю следующее исключение:
Microsoft.Data.Sqlite.SqliteException: SQLite Error 1: 'no such table: Issues'.