.NET(Entity Framework Core)を使うならSQL Serverを使っておけ、というのが正直なところなのだけれど、MySQLを使ってみたいと思うこともあるだろう。
ので試した。ASP.NETにはASP.NET Identityという認証ライブラリがあって、Webアプリケーション作成時にチェックボックスを入れるだけでその基本的な構成が行われる。僕が一番好きなIdentiyです。
が、そうすると当然ながらSQL Server向けになっており、MySQLで使うにはちょっと手を加えなくてはならない。
とりあえずユーザー登録とログインができるようになるためにやったことをメモしておく。
Entity Framework Coreのコードファーストマイグレーションを使うのが前提です。
.NET 5 で MySQL を使う
Connector/NET 8.0.23でサポートされているようだ。
Microsoft.EntityFrameworkCore.SqlServer
パッケージを削除(使わないので)MySql.EntityFrameworkCore
パッケージを追加(使うので)- 2021-2-18現在プレリリースなのでパッケージマネージャではプレリリース版にチェックを入れないと出てこない
UseSqlServer
をUseMySQL
に変更
Update-Database Errror
とりあえずUpdate-Database
してみたらエラーした。
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
これは僕の構成が悪いのかもしれないが、何が悪いのか調べるのは面倒くさかったのでIDesignTimeDbContextFactory
を実装してしのいだ。
code:ApplicationDbContextFactory.cs using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; namespace Application1.Data { public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> { public ApplicationDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>(); optionsBuilder.UseMySQL("server=localhost;database=application1;user=root;password=root-password"); return new ApplicationDbContext(optionsBuilder.Options); } } }
ASP.NET Identiy 対応(2021-02-19追記分)
先にこの後書いた対応をしていたけれど、追加でMigrationを作っていくと不整合が起きていった。生成されたマイグレーションを置換するのはやめて、ちゃんとEntityの定義を変えてあげたほうがよさそうだった。
- 既定のDBContextで使われるEntityのProperty属性を指定やる
- カスタマイズした各EntityのProperty属性を指定する
どちらかをしてやればいい。
1の場合は以下のような感じになる。これでもともと存在するMigrationファイルを削除した後単に Add-Migration すればキー長超過するテーブルがなくなった。
{ public class ApplicationDbContext : IdentityDbContext { protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<IdentityUser>(b => b.Property(p => p.Id).HasMaxLength(128)); builder.Entity<IdentityRole>(b => b.Property(p => p.Id).HasMaxLength(128)); builder.Entity<IdentityUserLogin<string>>(b => { b.Property(p => p.LoginProvider).HasMaxLength(128); b.Property(p => p.ProviderKey).HasMaxLength(128); }); builder.Entity<IdentityUserToken<string>>(b => { b.Property(p => p.LoginProvider).HasMaxLength(128); b.Property(p => p.Name).HasMaxLength(128); }); } } }
2の場合は自分で定義したEntity(ApplicationUserとかApplicationRoleとか)に同様にPropertyの属性を指定してやればいい。
ASP.NET Identiy 対応
さしあたってこれでユーザー登録とログインは可能だった。
- 既定のMigration構成はSQL Server向けなので削除する。
- Webアプリケーション作成時の認証を有効にした時にスキャフォルドされるやつ。
- 改めて Add-Migration する。
- そのままだとプライマリキー長を超過しているスキーマになるので適当に長さを変える。
ググれよ
先の対応をしてからググったらそりゃ例はあった。
- https://docs.microsoft.com/ja-jp/aspnet/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider
- http://surferonwww.info/BlogEngine/post/2020/05/14/aspnet-core-identity-to-use-mysql.aspx
- http://surferonwww.info/BlogEngine/post/2020/05/06/how-to-use-mysql-for-aspnet-identity.aspx
使ってる.NET 5ではなくパッケージが古い(MySql.Data.EntityFrameworkCore
)版だったので先にググっていたら同じ手法では動かなかったかもしれない。
結果オーライ。
もっとちゃんとググると公式な.NET 5ドキュメントも見つかるかもしれないが、それを試すには今日はもう遅すぎる。