《Entity Framework 6 Recipes》中文翻譯系列 (24) ------ 第五章 加載實體和導航屬性之查詢內存對象

翻譯的初衷以及爲何選擇《Entity Framework 6 Recipes》來學習,請看本系列開篇javascript

5-4  查詢內存對象

問題html

  你想使用模型中的實體對象,若是他們已經加載到上下文中,便不用與數據庫發生交互。另外,你想使用Code-First來管理數據訪問。java

解決方案數據庫

  假設你有如圖5-12所示的模型。框架

圖5-12 一個包含Club實體對象的簡單模型ide

 

  在Visual Studio中添加一個名爲Recipe4的控制檯應用,並確保引用了實體框架6的庫,NuGet能夠很好的完成這個任務。在Reference目錄上右鍵,並選擇 Manage NeGet Packages(管理NeGet包),在Online頁,定位並安裝實體框架6的包。這樣操做後,NeGet將下載,安裝和配置實體框架6的庫到你的項目中。學習

  建立一個名爲Club類,複製代碼清單5-8中的屬性到這個類中,建立club實體。 ui

代碼清單5-8. Club實體類this

1 public class Club
2     {
3         public int ClubId { get; set; }
4         public string Name { get; set; }
5         public string City { get; set; }
6     }

   

   接下來,建立一個名爲Recipe4Context的類,並將代碼清單5-9中的代碼添加到其中,並確保其派生到DbContext類。spa

代碼清單5-9. 上下文對象Recipe4Contex

複製代碼
 1  public class Recipe4Context : DbContext  2  {  3 public Recipe4Context()  4 : base("Recipe4ConnectionString")  5  {  6 // 禁用實體框架的模型兼容性  7 Database.SetInitializer<Recipe3Context>(null);  8  }  9 10 protected override void OnModelCreating(DbModelBuilder modelBuilder) 11  { 12 modelBuilder.Entity<Club>().ToTable("Chapter5.Club"); 13  } 14 15 public DbSet<Club> Clubs { get; set; } 16 }
複製代碼

 

  接下來添加App.Config文件到項目中,並使用代碼清單5-10中的代碼添加到文件的ConnectionStrings小節下。

代碼清單5-10. 鏈接字符串

複製代碼
<connectionStrings>
<add name="Recipe4ConnectionString" connectionString="Data Source=.; Initial Catalog=EFRecipes; Integrated Security=True; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /> </connectionStrings>
複製代碼

 

   在這個模型中,咱們有一個實體類型Club,你能夠經過查詢獲取各類各樣的俱樂部(Clubs). 咱們能夠經過查詢DbSet的屬性Local來減小與數據庫的交互。它是對Club實體的包裝。屬性Local 公佈了一個內存實體對象的動態集合(Observable Collection),與上下文對象保持同步。代碼清單5-11演示了Local動態集合的用法。

代碼清單5-11. DbSet對象中Local 屬性的通常用法

 1        int desertSunId;
 2 
 3             using (var context = new Recipe4Context())
 4             {
 5                 var starCity = new Club {Name = "Star City Chess Club", City = "New York"};
 6                 var desertSun = new Club {Name = "Desert Sun Chess Club", City = "Phoenix"};
 7                 var palmTree = new Club {Name = "Palm Tree Chess Club", City = "San Diego"};
 8 
 9                 context.Clubs.Add(starCity);
10                 context.Clubs.Add(desertSun);
11                 context.Clubs.Add(palmTree);
12 
13                 context.SaveChanges();
14 
15                 desertSunId = desertSun.ClubId;
16             }
17 
18             using (var context = new Recipe4Context())
19             {
20                 Console.WriteLine("\nLocal Collection Behavior");
21                 Console.WriteLine("=================");
22 
23                 Console.WriteLine("\nNumber of Clubs Contained in Local Collection: {0}", context.Clubs.Local.Count);
24                 Console.WriteLine("=================");
25 
26                 Console.WriteLine("\nClubs Retrieved from Context Object");
27                 Console.WriteLine("=================");
28                 foreach (var club in context.Clubs.Take(2))
29                 {
30                     Console.WriteLine("{0} is located in {1}", club.Name, club.City);
31                 }
32 
33                 Console.WriteLine("\nClubs Contained in Context Local Collection");
34                 Console.WriteLine("=================");
35                 foreach (var club in context.Clubs.Local)
36                 {
37                     Console.WriteLine("{0} is located in {1}", club.Name, club.City);
38                 }
39 
40                 context.Clubs.Find(desertSunId);
41 
42                 Console.WriteLine("\nClubs Retrieved from Context Object - Revisted");
43                 Console.WriteLine("=================");
44                 foreach (var club in context.Clubs)
45                 {
46                     Console.WriteLine("{0} is located in {1}", club.Name, club.City);
47                 }
48 
49                 Console.WriteLine("\nClubs Contained in Context Local Collection - Revisted");
50                 Console.WriteLine("=================");
51                 foreach (var club in context.Clubs.Local)
52                 {
53                     Console.WriteLine("{0} is located in {1}", club.Name, club.City);
54                 }
55 
56                 //獲取local集合的引用 
57                 var localClubs = context.Clubs.Local;
58 
59                 // 添加一個新的 Club
60                 var lonesomePintId = -999;
61                 localClubs.Add(new Club
62                     {
63                         City = "Portland",
64                         Name = "Lonesome Pine",
65                         ClubId = lonesomePintId
66                     });
67 
68                 // 刪除 Desert Sun club
69                 localClubs.Remove(context.Clubs.Find(desertSunId));
70 
71                 Console.WriteLine("\nClubs Contained in Context Object - After Adding and Deleting");
72                 Console.WriteLine("=================");
73                 foreach (var club in context.Clubs)
74                 {
75                     Console.WriteLine("{0} is located in {1} with a Entity State of {2}",
76                                       club.Name, club.City, context.Entry(club).State);
77                 }
78 
79                 Console.WriteLine("\nClubs Contained in Context Local Collection - After Adding and Deleting");
80                 Console.WriteLine("=================");
81                 foreach (var club in localClubs)
82                 {
83                     Console.WriteLine("{0} is located in {1} with a Entity State of {2}",
84                                       club.Name, club.City, context.Entry(club).State);
85                 }
86 
87                 Console.WriteLine("\nPress <enter> to continue...");
88                 Console.ReadLine();

代碼清單5-11的輸出以下:

Local Collection Behavior
=================
Number of Clubs Contained in Local Collection: 0
=================
Clubs Retrieved from Context Object
=================
Star City Chess Club is located in New York
Desert Sun Chess Club is located in Phoenix
Clubs Contained in Context Local Collection
=================
Star City Chess Club is located in New York
Desert Sun Chess Club is located in Phoenix
Clubs Retrieved from Context Object - Revisted
=================
Star City Chess Club is located in New York
Desert Sun Chess Club is located in Phoenix
Palm Tree Chess Club is located in San Diego
Clubs Contained in Context Local Collection - Revisted
=================
Star City Chess Club is located in New York
Desert Sun Chess Club is located in Phoenix
Palm Tree Chess Club is located in San Diego
Clubs Contained in Context Object – After Adding and Deleting
=================
Star City Chess Club is located in New York with a Entity State of Unchanged
Desert Sun Chess Club is located in Phoenix with a Entity State of Deleted
Palm Tree Chess Club is located in San Diego with a Entity State of Unchanged
Clubs Contained in Context Local Collection – After Adding and Deleting
=================
Star City Chess Club is located in New York with a Entity State of Unchanged
Palm Tree Chess Club is located in San Diego with a Entity State of Unchanged
Lonesome Pine is located in Portland with a Entity State of Added

原理

   這個示例使用Club實體對象。開始,咱們從Local屬性公佈的動態集合中獲取Club實體對象的數量。注意,圖5-13沒有SQL查詢產生,由於一個對Local屬性的查詢,是不會產生針對數據庫的SQL查詢的。

圖5-13 訪問Local動態集合,不會產生一個SQL查詢

   如今,結果爲0,由於咱們尚未經過上下文對象執行一個關於Clubs的查詢。記住,Local動態集合會自動地與上下文對象保持同步。

  接下來,咱們經過上下文對象在數據庫中查詢前面兩個Club實體。並循環輸出他們的名稱和地點。如圖5-14所示。

圖5-14 查詢上下文對象,老是產生一個SQL查詢

 

   隨後,咱們當即循環相應的Local集合,獲得了相同的結果。記住,結果集徹底同樣,由於Local集合自動與DbContext保持同步。若是新的實體被獲取到上下文,經過這些實體,Loacal集合會被自動更新。注意,圖5-15中,當訪問Local集合時,沒有SQL查詢生成。

圖5-15 訪問 local集合,沒有生成SQL語句

 

   爲了進一步演示Local屬性的默認行爲,咱們經過上下文查詢獲取第三個Club實體,咱們又一次循環上下文對象和Local集合,一樣獲得了相同的結果。圖5-16中,經過查詢上下文對象的查詢產生了一個SQL語句,圖5-17中,能通查詢Local集合的查詢,沒有產生任何SQL語句。

圖5-16 查詢上下文對象,老是產生一個SQL查詢

 

圖5-17  訪問 local集合,沒有生成SQL語句

   接下來,咱們添加一個名爲 Lonesone Pine Club實體到Local集合中,同時,咱們從Local集合中刪除Desert Sun Club. 而後咱們枚舉上下文對象中的Clubs,正如指望的那樣,一個SQL查詢產生了,如圖5-18所示。

圖5-18 查詢上下文對象,老是產生一個SQL查詢

   有趣的是,咱們看到,在上下文中Desert Sun Club已經被標記爲刪除,但咱們沒有看到最新添加的Lonesome Pine Club對象。記住,Lonesome Pine Club已經被添加到上下文中,但咱們尚未調用SaveChanges()方法更新到底層據庫中

  然而,當咱們枚舉Local集合時,沒有產生針對底層數據庫的查詢,如圖5-19所示。相反,咱們看到了最新添加的Lonesome Pine Club對象,但咱們再也不看到標記爲刪除的Desert Sun Club對象。 Loacl集合的默認行爲是,隱藏任何標記爲刪除的對象,由於這些對象不於有效

圖5-19  訪問 local集合,沒有生成SQL語句

  

  本質:訪問Local集合不會產生針對底層數據庫的SQL查詢,訪問上下中的屬性集合老是會產生一個被髮送到數據庫中的SQL是查詢

  總之,名爲Local的屬性公佈的實體集,是一個動態的集合(Observale Collection)(譯註:也有人譯爲,可觀察的集合,但綜合該對象的做用和功能來看,我的認爲譯爲動態集合更恰當一些),它是上下文內容的一個鏡像。正如本小節演示的那樣,查詢Local集合很是有效,由於它不會產生針對底層數據庫的SQL查詢。

 

 

 

實體框架交流QQ羣:  458326058,歡迎有興趣的朋友加入一塊兒交流

謝謝你們的持續關注,個人博客地址:http://www.cnblogs.com/VolcanoCloud/

相關文章
相關標籤/搜索