[Entity Framework][Code First]One-to-One Relationships

一對一關係

One-to-One Relationships

前言

終於講到最後一個類別之間的關聯了,要達成一對一的關係,只要在各加上References Property,就可以很簡單完成一對一關係。 如下:

[Table("Person")]
public class Person
{
    [Key]
    public int PersonId { get; set; }

    public string Name { get; set; }

    public Photo Photo { get; set; }
}

[Table("Photo")]
public class Photo
{
    [Key]        
    public int PersonId { get; set; }

    public byte[] Image { get; set; }

    public string Caption { get; set; }

    public Person Person { get; set; }
}

這樣設計讓Code First建立資料庫後,會發現拋出Exception

為什麼會這樣?

這是因為Person參考Photo、Photo又參考Person,Code First無法決定是誰依賴誰,意味著建立資料庫的時候不知道要把foreign key建立在Person還是Photo底下

依照此例子的情況,我們是希望Photo依賴Person,所以要解決這個問題,要讓Code First知道Photo有foreign key,藉由此方式讓Code First知道Photo依賴Person。 如下:

[Table("Photo")]
public class Photo
{
    [Key]
    [ForeignKey("Person")]
    public int PersonId { get; set; }

    public byte[] Image { get; set; }

    public string Caption { get; set; }

    public Person Person { get; set; }
}

產生後的資料庫,就如我們預期的,Photo依賴Person

使用Fluent API方式

public class PhotoConfiguration : EntityTypeConfiguration<Photo>
{
    public PhotoConfiguration()
    {            
        HasRequired(p => p.Person)
        .WithOptional(p => p.Photo);
    }
}

public class PersonConfiguration : EntityTypeConfiguration<Person>
{
    public PersonConfiguration()
    {
        HasRequired(p => p.Photo)
        .WithRequiredPrincipal(p => p.Person);
    }
}

 

Photo要是必需的

依照這種設計方式,還隱藏的另一個問題,就是新增Photo的時候一定要有Person,但是新增Person的時候不一定要有Photo。

所以如果需求上有要求新增Person的時候,也一定要有Photo,則我們要加上Required Attribute,來強制新增Person的時候一定要有Photo。 如下

[Table("Person")]
public class Person
{
    [Key]
    public int PersonId { get; set; }

    public string Name { get; set; }

    [Required]
    public Photo Photo { get; set; }
}

驗證Required

using (var db = new Model1())
{
    var p = new Person()
    {
        Name = "Miles"
    };

    db.Person.Add(p);
    db.SaveChanges();
}

執行後Entity Framework會驗證Photo是必須的,而拋出Exception

使用Fluent API

public class PhotoConfiguration : EntityTypeConfiguration<Photo>
{
    public PhotoConfiguration()
    {            
        HasRequired(p => p.Person)
        .WithRequiredDependent(p => p.Photo);
    }
}

備註:使用Fluent API待確認,因為書上說明用這樣的方式可以達到Requrired,可是筆者這邊這麼try都無法成功。

 

 

 

 

 

一天一分享,身體好健康。

該追究的不是過去的原因,而是現在的目的。