0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EFCoreでMariaDB(MySQL)の主キーでない列にAUTO_INCREMENTをつける

Posted at

はじめに

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

作業

モデル

Model/Report.cs
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

ApplicationDbContext.cs
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を設定できました。

image.png
できたテーブル

うまくいかなかったやり方

最初に試してうまくいかなかったやり方も載せておきます。

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

まとめ

間違いなどありましたらご指摘いただければとおもいます。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?