✍️

Entity Framework Coreでモデルをカスタマイズする

に公開

背景

C#でWeb APIを実装している中で、自身で定義したデータモデルがEFCoreにマッピングできず、エラーになった。
そのため、解決策を調査し、実際に動作することを確認したので、残しておく。
EFCoreに対しての理解が深まった。

解決策

ApplicationDbContextのOnModelCreatingメソッドを使用し、Owned Entityを設定する。

実装例

  • Userクラスに、UserNameクラスを持ったモデルを定義する
  • UlidはEFCoreが自動で主キーとして認識できない
  • ModelBuilderを使用する
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        // added to ensure the primary key is set correctly
        builder.HasKey(u => u.Id);

        // added to ensure the Ulid is converted correctly
        builder.Property(u => u.Id)
            .HasConversion(
                id => id.ToString(),
                str => Ulid.Parse(str));

        // configures UserName as an owned entity
        builder.OwnsOne(u => u.Name, nameBuilder =>
        {
            // set index to Value property by uilder method
            nameBuilder.Property(n => n.Value)
                .HasMaxLength(50)
                .IsRequired();

            // Indexes are set for the properties of the owning entity
            nameBuilder.HasIndex("Value").IsUnique();
        });
    }
}

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    public DbSet<User> Users { get; set; } = null!;

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        new UserEntityTypeConfiguration().Configure(modelBuilder.Entity<User>());
    }
}

最後

この方法で実装後に、さらに調査したら以下の方法でも改善できるかも
https://learn.microsoft.com/ja-jp/ef/core/modeling/entity-types?tabs=data-annotations

Discussion