01
2019

ASP.NET Core IdentityテーブルのIndex column size too largeの対処

CATEGORY.NET
ASP.NET Coreネタ二個目。ASP.NET Core標準のユーザー認証(?)のASP.NET Core Identityは、勝手にユーザーテーブルとか作ってくれるわけだが、ちょっと古いMySQLのutf8mb4データベースだと、自動生成されるテーブル定義が有名な「Index column size too large. The maximum column size is 767 bytes.」に引っかかってしまってマイグレーションエラーになる。

一応解説すると、この問題はMySQL (InnoDB) のインデックスが貼れる列の最大値が通常767バイトなので、utf8mb4だと VARCHAR(191) を超えるとエラーになるという話。自動生成されるテーブルは、列が VARCHAR(255) なのでアウトである。

最新のMySQLなら最大値が上がってて大丈夫とかそういう話もあるけど、今回はアプリ側で列サイズを191文字まで削って対応しようとした。
が、自動生成のテーブルはEntityクラスが無いので、いつものアノテーションでは列サイズが設定できない。
どうしようかと思ったら、Fluent APIなら普通に自動生成のテーブルもカスタマイズできたのでそれで対応した。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<IdentityUser<int>>(entity =>
{
entity.Property(m => m.Email).HasMaxLength(191);
entity.Property(m => m.NormalizedEmail).HasMaxLength(191);
entity.Property(m => m.NormalizedUserName).HasMaxLength(191);
entity.Property(m => m.UserName).HasMaxLength(191);
});
modelBuilder.Entity<IdentityRole<int>>(entity =>
{
entity.Property(m => m.Name).HasMaxLength(191);
entity.Property(m => m.NormalizedName).HasMaxLength(191);
});
modelBuilder.Entity<IdentityUserLogin<int>>(entity =>
{
entity.Property(m => m.LoginProvider).HasMaxLength(191);
entity.Property(m => m.ProviderKey).HasMaxLength(191);
});
modelBuilder.Entity<IdentityUserToken<int>>(entity =>
{
entity.Property(m => m.LoginProvider).HasMaxLength(191);
entity.Property(m => m.Name).HasMaxLength(191);
});
}
こんな感じ。Entityを継承して使っている場合はそちらを指定する。

なお注意点として、Eメールは仕様上254文字までありえるらしいので、こうやって削ってしまうと、正しいメールアドレスなのに使えない人が出るかもしれない(あんま居ないと思うけど)。
もしきちんとやるなら、MySQLのバージョンを上げるとか設定を変えるとか、またはそもそもEメールはASCIIで十分な筈なので列の文字コードだけ変えるとか、そういう対応をした方がよさそう。
スポンサーサイト



Tag: ASP.NET .NET MySQL

0 Comments

Leave a comment