【.NET MAUI 】EntityFrameworkCore のマイグレーションができない時の対処法
MAUI プロジェクトで EntityFrameworkCore を使おうとしたら一筋縄ではいかなかったのでメモ。
現象
MAUI プロジェクトにて、以下のチュートリアルに従って作業を進める。
手順
- Microsoft.EntityFrameworkCore.Sqlite の Nuget パッケージを MAUI プロジェクトに追加
- Model.cs の作成
// using, 名前空間 は適宜
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public string DbPath { get; }
public BloggingContext()
{
var folder = Environment.SpecialFolder.LocalApplicationData;
var path = Environment.GetFolderPath(folder);
DbPath = System.IO.Path.Join(path, "blogging.db");
}
// The following configures EF to create a Sqlite database file in the
// special "local" folder for your platform.
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
- マイグレーション用のツール、パッケージを追加
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
- 初回マイグレーションの実行
dotnet ef migrations add InitialCreate
← ここで以下のようなエラーが発生
$ dotnet ef migrations add InitialCreate
Build started...
Build failed. Use dotnet build to see the errors.
原因
こちらの GitHub の Issue のコメントによると、
- マイグレーション時にアプリケーションコードを実行する必要アリ
- 実行には .NET Core もしくは .NET Framework のランタイムが必要
- ランライムはプロジェクトから借用
- Xamarin などはランタイムが .NET Standard なのでダメ
とのことです。
解決方法
Model を別プロジェクト(クラスライブラリ)に切り出し、また別に、ツール実行用のコンソールプロジェクトを作成し、そのコンソールプロジェクトでマイグレーションを実行することで解決します。
別 issue ですがこちらを参考にしました。
手順
1. 〇〇.Model という名前のプロジェクト作成
〇〇(MAUIプロジェクト名).Model という名前のプロジェクトを同じソリューション内に作成し、そのプロジェクトに Model.cs を移動させます。
ただ移動させただけだと Microsoft.EntityFrameworkCore.Sqlite
がないというエラーが出るので、必要なパッケージを NuGet マネージャから追加しておきます。
2. 不要なパッケージの削除、プロジェクト参照の追加
MAUI 側では EntityFrameworkCore のパッケージは必要なくなるので削除します。今回は、 Nuget マネージャから追加した Microsoft.EntityFrameworkCore.Sqlite
と、コマンドラインから追加した Microsoft.EntityFrameworkCore.Design
を削除します。
また、先ほど作成した 〇〇.Model プロジェクトへの参照を MAUI プロジェクトに追加します。
3. マイグレーション実行用のコンソールプロジェクトの作成
また新しく 〇〇.Console というプロジェクトを作成し、そのプロジェクトに 〇〇.Model へのプロジェクト参照と、Microsoft.EntityFrameworkCore.Tools
の NuGet パッケージを追加します。
これで、マイグレーションのための準備は完了です。
4. マイグレーション実行
マイグレーションの実行は、ソリューションがあるディレクトリをカレントディレクトリにして、以下のように実行します。
対象プロジェクトに 〇〇.Model を、スタートアッププロジェクトに 〇〇.Console を指定するところがポイントです。
dotnet ef migrations add InitialCreate --project=MauiEfcore.Model --startup-project=MauiEfcore.Console
Discussion