読者です 読者をやめる 読者になる 読者になる

Entity Framework - 複合型のマッピング先のカラム名を変更する

Entity Frameworkで特に指定しない場合、複合型(ComplexType)は「{プロパティ名}_{複合型のプロパティ名}」という名前のカラムにマッピングされます。たとえば次のようになります。

エンティティ

// メールアドレス(複合型)
public class MailAddress {
    public string Address { get; set; }
    public string DisplayName { get; set; }
}

// メール送信ログ(複合型のプロパティを2つ持つ)
public class MailLog {
    public int Id { get; set; }
    public MailAddress From { get; set; }
    public MailAddress To { get; set; }
}

マッピングされるテーブル

create table MailLogs(
    Id int identity(1, 1) not null,
    From_Address varchar(50) not null,
    From_DisplayName nvarchar(50) not null,
    To_Address varchar(50) not null,
    To_DisplayName nvarchar(50) not null,
    constraint PK_MailLogs primary key(Id)
);

正直個人的な好みなんですが、カラム名の「_(アンダースコア)」を取りたいなと思って方法を探しました。

Fluent APIを使うと次のようなコードを書くことになります。

public class AppDbContext : DbContext {
    public IDbSet<MailLog> MailLogs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);

        // ついでにテーブル名は単数形がいい
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        // 複合型のプロパティに対してカラム名を指定する
        modelBuilder.Entity<MailLog>().Property(entity => entity.From.Address).HasColumnName("FromAddress");
        modelBuilder.Entity<MailLog>().Property(entity => entity.From.DisplayName).HasColumnName("FromDisplayName");
        modelBuilder.Entity<MailLog>().Property(entity => entity.To.Address).HasColumnName("ToAddress");
        modelBuilder.Entity<MailLog>().Property(entity => entity.To.DisplayName).HasColumnName("ToDisplayName");
    }
}

マッピングされるテーブル

-- ついでにテーブル名が単数形になっている
create table MailLog(
    Id int identity(1, 1) not null,
    -- 以下HasColumnNameで指定したカラム名になっている
    FromAddress varchar(50) not null,
    FromDisplayName nvarchar(50) not null,
    ToAddress varchar(50) not null,
    ToDisplayName nvarchar(50) not null,
    constraint PK_MailLog primary key(Id)
);

DataAnnotationsを使った方法はわからずですが・・・。

参考