2017年2月12日日曜日

Entity Framework 1対1

コンソールアプリケーションで試します。
基本的なことはこちら→ConsoleApplicationでCodeFirst

1対1です。

1つのテーブルにまとめようとするとあるレコードはnullが
入る列とデータが入る列があるので分離してnullを排除した結果
1対1のテーブルになったとか、あると思いますが。

今までどおりに作成していくと、どちらのテーブルがどちらを参照するか表現できません。
そこで、Fluentd APIを利用します。

メインのテーブルと、そのIDを参照する参照テーブルで考えてみます。
model/TableMain.cs
namespace EntityFramework.model
{
    class TableMain
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public virtual TableRef TableRef { get; set; }
    }
}

model/TableRef.cs
namespace EntityFramework.model
{
    class TableRef
    {
        [Key]
        public int TableMainId { get; set; }

        public string Memo { get; set; }

        public virtual TableMain TableMain { get; set; }
    }
}

TableMainIdがTableMainテーブルのidを参照する流れです。
ただし、TableMain.csもTableRef.csもともに public virtual クラス名 で記載しているので
どちらがどちらを参照しているのか、この情報だけだと判断がつきません。
ためしに、Add-Migrationを行うと

model/SampleContext.cs(NG)
using System.Data.Entity;

namespace CodeFirst.model
{
    class SampleContext : DbContext
    {
        public DbSet TableMain { get; set; }
        public DbSet TableRef { get; set; }
    }
}

下記のように怒られます。
Unable to determine the principal end of an association between the types 'CodeFirst.model.TableRef' and 'CodeFirst.model.TableMain'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

fluent APIで解決する方法

model/SampleContext.cs
using System.Data.Entity;

namespace CodeFirst.model
{
    class SampleContext : DbContext
    {
        public DbSet TableMain { get; set; }
        public DbSet TableRef { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity()
            .HasRequired(t => t.TableRef)
            .WithRequiredPrincipal(t => t.TableMain);
        }
    }
}

HasMany →1:nの関連
HasRequired→1:1の関連
HasOptional→1:0..1の関連
-------------------------------------
data annotaionsで解決する方法

model/TableRef.cs
sing System.ComponentModel.DataAnnotations;

namespace CodeFirst.model
{
    class TableRef
    {
        [Key]
        public int TableMainId { get; set; }

        public string Memo { get; set; }
        [Required]
        public virtual TableMain TableMain { get; set; }
    }
}

[Required]を追加すると期待したリレーションが付きます

0 件のコメント:

コメントを投稿