はじめに
EFCoreでの設定からMariaDBにテーブルを作成する際に、主キーではないカラムにAUTO_INCREMENTを付けるための記述を残します。MySQLでも同様のはずです…
どのような場面でつかうかは不明ですが、調べていてどうすれば目的のテーブルをCREATEできるのか気になったので共有しておきます。
環境
・Windows 10
・VisualStudio 2022
・.NET6.0
・Microsoft.AspNetCore.Identity.EntityFrameworkCore 6.0.10
・Pomelo.EntityFrameworkCore.MySql 6.0.2
・MariaDB 10.9.3
作業
モデル
using System.ComponentModel.DataAnnotations;
namespace WebApplication.Models
{
public class Report
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ReportId { get; set; }
public string ReportName { get; set; }
public int AutoIncrementCol { get; set; }
}
}
AutoIncrementCol が今回のAutoIncrementさせる列です。
ReportIdはintの主キーなので、なにも設定しないと自動でAUTO_INCREMENTが付与されます。なので無効にします。
また、MySQLの仕様で1つのテーブルで複数カラムにAUTO_INCREMENTを設定することはできません。
ApplicationDbContext
using WebApplication.Models.IdentityModels;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using WebApplication.Models;
using System.Reflection.Emit;
namespace WebApplication.Data
{
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Report>().HasAlternateKey(a => a.AutoIncrementCol);
builder.Entity<Report>().Property(p => p.AutoIncrementCol).ValueGeneratedOnAdd();
}
public DbSet<Report> Report { get; set; }
}
}
HasAlternateKey()でテーブルに対してキーの追加を行い、
ValueGeneratedOnAdd()でAUTOINCREMENTさせます。
update-database
マイグレーションファイルをつくって適用。
PM> update-database
Build started...
Build succeeded.
(中略)
CREATE TABLE `Report` (
`ReportId` int NOT NULL,
`ReportName` longtext CHARACTER SET utf8mb4 NOT NULL,
`AutoIncrementCol` int NOT NULL AUTO_INCREMENT,
CONSTRAINT `PK_Report` PRIMARY KEY (`ReportId`),
CONSTRAINT `AK_Report_AutoIncrementCol` UNIQUE (`AutoIncrementCol`)
) CHARACTER SET=utf8mb4;
(以下略)
これで主キーではないカラムにAUTO_INCREMENTを設定できました。
うまくいかなかったやり方
最初に試してうまくいかなかったやり方も載せておきます。
HasIndex
builder.Entity<Report>().HasIndex(a => a.AutoIncrementCol).IsUnique();
builder.Entity<Report>().Property(p => p.AutoIncrementCol).ValueGeneratedOnAdd();
さきほどのOnModelCreating()内の記述でHasIndex().IsUnique()すればいいよ、みたいな検索結果がでてくるのですが、古いのかMariaDB(MySQL)に対応してないのか不明ですがうまくいかなかったです。
PM> update-database
Build started...
Build succeeded.
(中略)
Failed executing DbCommand (16ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `Report` (
`ReportId` int NOT NULL,
`ReportName` longtext CHARACTER SET utf8mb4 NOT NULL,
`AutoIncrementCol` int NOT NULL AUTO_INCREMENT,
CONSTRAINT `PK_Report` PRIMARY KEY (`ReportId`)
) CHARACTER SET=utf8mb4;
(中略)
Incorrect table definition; there can be only one auto column and it must be defined as a key
作成時にいったんテーブルを作成してからHasIndex()のINDEXを追加しているようで、AUTO_INCREMENTを付与するには作成時にキーがないといったエラーになります。
[Index]
インデックスの書き方は以下のようにも書けますが結果は同じです。
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IdentityApplication.Models
{
[Index(nameof(AutoIncrementCol),IsUnique = true)]
public class Report
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ReportId { get; set; }
public string ReportName { get; set; }
public int AutoIncrementCol { get; set; }
}
}
あと列名に[Index]を書くやり方もあるみたいですがMicrosoft.EntityFrameworkCoreのほうしか見当たらず、試せてないです。
Code First Data Annotations - EF6 | Microsoft Learn
IndexAttribute クラス (Microsoft.EntityFrameworkCore) | Microsoft Learn
まとめ
間違いなどありましたらご指摘いただければとおもいます。
参考