Entity Framework 4.1 之四:復雜類型
原文名稱:Entity Framework 4.1: Complex Types (4)
原文地址:http://vincentlauzon.wordpress.com/2011/04/13/entity-framework-4-1-complex-types-4/
默認情況下,EF4.1 將類映射到表,這是約定,但是有時候,我們需要模型比表的粒度更細一些。
地址是一個典型的例子,看一下下面的客戶類。
{
publicint ClientID { get; set; }
[Required]
[StringLength(32, MinimumLength=2)]
publicstring ClientName { get; set; }
public Address ResidentialAddress { get; set; }
public Address DeliveryAddress { get; set; }
}
publicclass Address
{
[Required]
publicint StreetNumber { get; set; }
[Required]
[StringLength(32, MinimumLength=2)]
publicstring StreetName { get; set; }
}
我們不希望其中的兩個地址屬性都映射到地址表中的記錄,而是讓 EF4.1 都映射到一張表中,將地址展開,如何做到呢?可以通過復雜類型。
像我們前面看到的,我們總是通過標簽或者模型構建器來覆蓋默認約定。我提到過,當我們豐富業務模型的時候,例如必填項,我建議使用屬性。現在我考慮將類中的復雜屬性映射到表中的字段,所以這里不是用標簽,而是使用模型構建器。
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Client>().Property(x => x.ClientID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.ComplexType<Address>();
modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetNumber).HasColumnName("ResStreetNumber");
modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetName).HasColumnName("ResStreetName");
modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetNumber).HasColumnName("DelStreetNumber");
modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetName).HasColumnName("DelStreetName");
}
首先,我指定 client-id 作為自動增長的標識列。然后,指定 Address 是復雜類型。如果愿意的話,也可以將 [ComplexType] 標簽加到類上來說明。然后,使用 Lambda 表達式將每一個子屬性映射到列上,這將會生成如下的表。

現在,可以使用模型了。
{
var client =new Client
{
ClientName ="Joe",
ResidentialAddress =new Address
{
StreetNumber =15,
StreetName ="Oxford"
},
DeliveryAddress =new Address
{
StreetNumber =514,
StreetName ="Nolif"
}
};
context1.Clients.Add(client);
context1.SaveChanges();
}
using (var context2 =new MyDomainContext())
{
var clients = from w in context2.Clients
where w.ClientName =="Joe"
select w;
foreach (var client in clients)
{
Console.WriteLine("client residential StreetNumber: "+ client.ResidentialAddress.StreetNumber);
Console.WriteLine("client residential StreetName: "+ client.ResidentialAddress.StreetName);
Console.WriteLine("client delivery StreetNumber: "+ client.DeliveryAddress.StreetNumber);
Console.WriteLine("client delivery StreetName: "+ client.DeliveryAddress.StreetName);
}
}
對于復雜類型,最值得注意的是空的管理。即使復雜類型的所有屬性都是可空的,你也不能將整個復雜類型的對象設為 null, 例如,在這種情況下,即使街道的名稱和街道的號碼不是必填的,也不能有一個住宅的地址為 null,需要創建一個所有屬性都是 null 的地址對象來表示。同樣的道理,當你獲取一個實體的時候,即使所有的屬性都是 null ,EF4.1 也將會創建一個復雜類型的對象。
浙公網安備 33010602011771號