在數據庫中,存在通過一張鏈接表來關聯兩張表的情況。鏈接表僅包含連接兩張表形成多對多關系的外鍵,你需要把這兩張多對多關系的表導入到實體框架模型中。
1.1 假設我們有如下數據關系:

我們有三張表用來存儲Album(專輯)、Artist(藝人)、LinkTable(專輯與藝人的關系表)。一張“專輯”可以有多個“藝人”,同時一個“藝人”也可以有多張專輯。
1.2 右鍵你的項目,使用entityframework的database first創建實體模型。注意把這三張表都選上,當點擊“完成”之後,實體框架生成的視圖如圖4-1

圖4-1
1.3 觀察圖4-1可以發現,Album與Artist之間的關系被映射成了一條多對多的直線,而當初選擇的LinkTable表沒有出現在視圖中。這是因為LinkTable中沒有標量屬性,也就是說沒有載荷。實體框架認為,LinkTable存在的意義就是表示Album與Artist之間的關系的,而上圖足以表示他兩的關系,所以LinkTable就沒有存在的必要了。但是如果LinkTable中有標量屬性,實體框架則會為他創建相應的模型,如下一節2.1。
1.4 對上述關系的插入與查詢測試。輸出如圖4-2

1 using (var context = new ef6recipesEntities())
2 {
3
4 // 添加一個擁有兩張專輯的藝術家
5 var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
6 var album1 = new Album { AlbumName = "Drive" };
7 var album2 = new Album { AlbumName = "Live at Texas Stadium" };
8 artist.Albums.Add(album1);
9 artist.Albums.Add(album2);
10 context.Artists.Add(artist);
11
12 //添加兩個藝術家的專輯
13 var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
14 var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
15 var album = new Album { AlbumName = "Honkytonk University" };
16 artist1.Albums.Add(album);
17 artist2.Albums.Add(album);
18 context.Artists.Add(artist1);
19 context.Artists.Add(artist2);
20
21 context.SaveChanges();
22 }
23
24 using (var context = new ef6recipesEntities())
25 {
26 Console.WriteLine("Artists and their albums...");
27 var artists = context.Artists;
28 foreach (var artist in artists)
29 {
30 Console.WriteLine("{0} {1}", artist.FirstName, artist.LastName);
31 foreach (var album in artist.Albums)
32 {
33 Console.WriteLine("\t{0}", album.AlbumName);
34 }
35 }
36 Console.WriteLine("\nAlbums and their artists...");
37 var albums = context.Albums;
38 foreach (var album in albums)
39 {
40 Console.WriteLine("{0}", album.AlbumName);
41 foreach (var artist in album.Artists)
42 {
43 Console.WriteLine("\t{0} {1}", artist.FirstName, artist.LastName);
44 }
45 }
46 }
View Code

圖4-2
在數據庫中,存在通過一張鏈接表來關聯兩張表的情況。鏈接表除了包含連接兩張表形成多對多關系的外鍵外,還包含一些額外的屬性,你需要把這兩張多對多關系的表導入到實體框架模型中。
2.1 假設我們有如下關系:

一個訂單(Order)可以擁有多個訂單項(Item),一個訂單項(Item)可以屬於多個訂單(Order),在連接Order、Item實例的關系上有一個Count屬性,這個屬性被稱為一個有效載荷。
2.2 和上節的一樣,右鍵你的項目,使用entityframework的database first創建實體模型。注意把這三張表都選上,當點擊“完成”之後,實體框架生成的視圖如圖4-2-1

圖4-2-1
2.3 觀察上圖可以發現與上節生成的視圖有些不同。這次生成的視圖好像更符合數據庫中標的結構一樣。Order與Item之間的多對多關系,被映射成兩個一對多的關系,即Order與OrderItem的一對多、Item與OrderItem的一對多。
2.4 對上述關系的插入與查詢測試。輸出如圖4-2-2

1 using (var context = new ef6recipesEntities1())
2 {
3 var order = new Order
4 {
5 OrderId = 1,
6 OrderDate = new DateTime(2010, 1, 18)
7 };
8 var item = new Item
9 {
10 SKU = 1729,
11 Description = "Backpack",
12 Price = 29.97
13 };
14 var oi1 = new OrderItem { Order = order, Item = item, Count = 1 };
15 item = new Item
16 {
17 SKU = 2929,
18 Description = "Water Filter",
19 Price = 13.97
20 };
21 var oi2 = new OrderItem { Order = order, Item = item, Count = 3 };
22 item = new Item
23 {
24 SKU = 1847,
25 Description = "Camp Stove",
26 Price = 43.99
27 };
28 var oi3 = new OrderItem { Order = order, Item = item, Count = 1 };
29 context.OrderItems.Add(oi1);
30 context.OrderItems.Add(oi2);
31 context.OrderItems.Add(oi3);
32 context.SaveChanges();
33 }
34
35 using (var context = new ef6recipesEntities1())
36 {
37 foreach (var order in context.Orders)
38 {
39 Console.WriteLine("Order # {0}, ordered on {1}",
40 order.OrderId.ToString(),
41 order.OrderDate.ToShortDateString());
42 Console.WriteLine("SKU\tDescription\tQty\tPrice");
43 Console.WriteLine("---\t-----------\t---\t-----");
44 foreach (var oi in order.OrderItems)
45 {
46 Console.WriteLine("{0}\t{1}\t{2}\t{3}", oi.Item.SKU,
47 oi.Item.Description, oi.Count.ToString(),
48 oi.Item.Price.ToString("C"));
49 }
50 }
51 }
View Code

圖4-2-2
最後,雖然ef支持無載荷模式,但是在項目中最好不要使用,因為一旦以後要把無載荷改成有載荷模式,實體關系也要隨之改變、程序代碼也要隨之改變,這樣造成很多不必要的麻煩。有一個好的解決辦法是,在項目的一開始就使用有載荷模式,即使我們的表在一開始是無載荷,我們也可以給他加一個隨機的屬性,使之變成有載荷模式。