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 之間的關聯。
一天一分享,身體好健康。
該追究的不是過去的原因,而是現在的目的。