[Entity Framework][Code First]Complex Types

Complex Types

前言

Code First能Complex Types來整理Domain class的訊息,可以讓Domain class使用起來更好懂。

像是把像同性質的的Properties放在一個類別底下,如Address

public class Person
{
    [Key]
    public int PersonId { get; set; }

    public int SocialNumber { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public Address Address { get; set; }   
}

public class Address
{        
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

使用起來,對應的table會是這樣。預設命名會加上Address。

如果不喜歡這樣的命名,可以使用Column Attribute來指定命名

[Column("StreetAddress")]
public string StreetAddress { get; set; }

 

說明

Convention

Complex types必須不包含Key值,如果包含Key值,就會符合一對多的Convention,Code First會建立兩個table

Complex types只能包含primitive properties

Complex types一定是single instance(單一實體),不能為collection type(集合)

Data Annotation [ComplexType]
Fluent modelBuilder.ComplexType<ClassName>()

 

Configuring Unconventional Complex Types

範例跟上面類別,差別在於Address多一個Key值欄位Id

public class Person
{
    [Key]
    public int PersonId { get; set; }

    public int SocialNumber { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public Address Address { get; set; }   
}

public class Address
{       
    public int Id { get; set; } 
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

此情形預設會產生兩筆table

遇到這種情況,就可以加上ComplexType Attribute,解決產生兩個table問題

[ComplexType]
public class Address
{
    public int Id { get; set; }        
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

 

More Complicated Complex Types

Convention有說明Complex Types只能包含primitive properties,所以如果Complex Types又包含其他class的話,則會Throw ModelValidationException,如下:

public class Person
{
    [Key]
    public int PersonId { get; set; }

    public PersonalInfo Info { get; set; }
}

public class PersonalInfo
{
    public Measurement Weight { get; set; }
    public Measurement Height { get; set; }    
}

public class Measurement
{
    public decimal Reading { get; set; }
    public string Units { get; set; }
}

這是因為Code First無法辨別PersonalInfo是一個Complex Type,而且也打破了Complex Types只能包含primitive properties的規則,所以如果遇到這種情況,要記得加上ComplexType Attribute,這樣Code First就可以辨別出來是Complex Type,並成功建立table。

[ComplexType]
public class PersonalInfo
{
    public Measurement Weight { get; set; }
    public Measurement Height { get; set; }
    public string DietryRestrictions { get; set; }
}

注意:

使用Complex Type一定要記得在建構式的地方new Complex Type,如下:

public class Person
{
    public Person()
    {
        this.Address = new Address();
        Info = new PersonalInfo
        {
            Weight = new Measurement(),
            Height = new Measurement()
        };
    }
    public Address Address { get; set; }

    public PersonalInfo Info { get; set; }
}

否則使用端沒有new Complex Type的話,會產生Null Exception。

 

小結

Code First Property Configurations 終於告一段落了,目前說明的Configurations已經在大部分的情況下夠用了,如果真的Code First沒辦法辦到一些資料庫比較特殊的情形,其實也只是需要手動去更動資料庫的設定而已。

Configurations講完後,接下來會開始分享Relationship,如何用Code First建立table 與 table 之間的關聯。

 

 

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

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