本文章是由機器翻譯。

資料點

Entity Framework 策略揭密,第 3 篇:類別、查詢和集合

朱莉列爾曼

這是一系列旨在説明您作出一些重要的決定,為您在應用程式中的資料訪問層使用實體框架時的資料點列第三。第一,關於在 2011 年 5 月問題模型創建工作流 (bit.ly/lOcjPz)、 討論選擇之間的代碼第一、 模型第一次和資料庫第一次的工作流。代碼首先不使用視覺化的模型,但資料庫第一次和模型第一次做。當你有,您將創建您的域類的視覺模型,一個在此列中的目標選擇將重點的代碼生成選項。在代碼生成的主題,我要看看使用 ObjectContext 和 DbContext 和 LINQ to 實體和實體 SQL 之間選擇之間進行選擇。

生成的類: EntityObjects 或波蘇斯嗎?

實體框架 (以下簡稱為簡潔起見 EF) 的第一個版本依靠 EntityObject 類,使與 ObjectContext 進行交互,因為它管理關係和跟蹤的更改為實體實例的實體。代碼生成確保從您的模型生成的類繼承 EntityObject。這仍然是預設用 Visual Studio 2010,但現在您有另一個選項。在 Microsoft。NET 框架 4、 EF 和其 ObjectContext 獲得能夠跟蹤更改和管理不取決於將通知發送給 ObjectContext EntityObject 實體之間的關係。這意味著您的類不再有繼承 EntityObject,這使得開發人員感興趣的持久性無知、 關注、 單元測試和其他軟體做法屬於敏捷開發的廣義傘分離一個巨大的差異。

不依賴于其它 Api 的類稱為平原老 CLR 物件或波蘇斯。使用這些清潔類,但仍執行其更改跟蹤和其他實體管理任務的 EF 能力稱為"POCO 支援"。這種支援的代碼第一次主幹。因為 EF 是能夠與 POCO 實體的工作,也可以由 EF 上下文管理在代碼第一次的情況下創建的類。

所以如果 EF 依賴于通知更改實體的上下文的 EntityObject,如何是它可能有波蘇斯,不但不繼承 EntityObject,有沒有知識的 EF?EF 使用兩條路徑,讓開發人員有他們諺語的蛋糕和也吃。不會更改的一件事是 ObjectContext 還需要瞭解哪些類是負責。

ObjectContext 獲取更明智的選擇,結果 POCO 支援的第一個路徑。NET 框架 4。現在的上下文是能夠檢查它管理的類。它具有新的方法,如 DetectChanges,將讀取它管理的物件,然後更新它跟蹤這些物件的狀態資訊。

時仍然能夠受益框架使用的代理物件形式的戲法位 EF 讓第二種方法使用波蘇斯。如果每一個 POCO 類屬性被標記為虛擬,EF 運行時將創建物件周圍的代理伺服器 (包裝) 和該代理是否與 EntityObject 相同的職業。代理類將通知上下文的屬性和關係的變化。您還可以利用代理伺服器而不會影響整個類。EF 將能夠延緩載入導航屬性標記為虛擬的即使其他屬性不是。

圖 1顯示為以實體的變化,使用 EntityObjects 或兩個的 POCO 機制之一 ObjectContext 現在可用的三種方式的視覺化表示形式。

圖 1實體框架軌道如何更改為實體

ObjectContext 或 DbContext?

EF 4.1 推出名為 DbContext 的 ObjectContext 的輕量的版。它提供了所有與 ObjectContext 相同的 POCO 支援。DbContext 還換一些更複雜的邏輯,所需的編碼對 ObjectContext 到更簡單的方法和屬性,使得在 EF 中執行的最常見的編碼任務變得更加容易。

DbContext 是用於代碼第一類的預設上下文,但 ObjectContext 是預設資料庫第一次與模型第一。Microsoft 提供備用的代碼生成範本為後者的兩種模式。第一個是 ADO。波蘇淨實體發電機。這將創建 POCO 類隨 ObjectContext 類來管理它們。第二,EF 4.1 安裝的一部分是 ADO。NET DbContext 發電機。這還會創建 POCO 類。但從 DbContext 到管理類生成的上下文類繼承。所以無論工作流你開始與 — — 代碼第一、 模型首或資料庫第一 — — 您已使用 DbContext,如果這是您的首選項選項。DbContext 有一個視窗到 ObjectContext,這樣您就可以獲得那裡如果需要。

查詢選項:LINQ 的實體或實體 SQL

開發人員有關于 EF 的另一個大問題是如果他們應使用 LINQ to 實體或實體 SQL 編寫和執行查詢。他們還要求兩個存在的理由。實體 SQL 是與實體資料模型中建其本機查詢語法來決定的。LINQ 是 C# 和 Visual Basic 的擴展和創建語言隊。當資料平臺組獲悉有關 LINQ 上所做的工作時,他們知道它會 EF 的查詢需要的自然延伸,所以他們創建 LINQ to 實體實施。

LINQ to 實體作為您的預設查詢策略

LINQ to 實體是 LINQ to 物件的實現。LINQ 使您可以編寫查詢針對強類型物件,並在的情況下 EF,您可以編寫查詢對實體類。LINQ 被表示兩種方式。第一個是與營辦商。查詢語句的樣子有點像 SQL 語句。查詢需要 EntityContainer,ObjectContext,這裡稱為上下文繼承的實例:

IQueryable<Family> query =
  from f in context.Families where f.Pets.Any() select f;

當您鍵入此運算式,智慧感知可説明您不只是強類型的類,但也使用 LINQ 的語法。 該查詢會返回 IQueryable 的家庭類型。 查詢仍需要,例如 ToList 的執行:

List<Family> reptileFamilies = query.ToList();

這將導致 EF 在資料庫上執行查詢,抓住從資料庫結果和創建使用這些結果的物件。

LINQ 查詢表示第二種方法是使用 LINQ 方法。 這些都需要 lambda 運算式作為其參數。 我會壓縮到一個 LINQ 查詢中的兩個前面的發言:

List<Family> reptileFamiles = 
  context.Families.Where(f=>f.Pets.Any()).ToList();

因為 LINQ 是如此簡單易用,快遞查詢 — 多虧了強類型和智慧感知 — — 我一般建議開發人員計畫使用 LINQ 作為其預設查詢策略。 你可以表達各種各樣的 LINQ 查詢。 此外,由於 LINQ 有許多實現,可能就已經好控制碼上使用它。 如果沒有,您很可能將受益于學習 LINQ to 實體和解決其他編碼問題使用 LINQ to 物件或其他很多口味 LINQ 之一。 另外,您可以找到很好的很多資源學習如何使用 LINQ 查詢。

實體 SQL 的邊緣案例查詢和其他語言

實體 SQL 是一種基於字串的查詢語法。 要執行使用實體 SQL 查詢,您需要使用 EF ObjectQuery 和實體 SQL 運算式中傳遞。 這看起來像什麼? 下麵是一個示例:

string eSql = "SELECT VALUE f FROM PetsModelContainer.Families AS f";
ObjectQuery<Family> query = context.CreateQuery<Family>(eSql);
List<Family> families = query.ToList();

像你創建 LINQ 的 IQueryable,此 ObjectQuery 仍需要執行以從資料庫中檢索結果。ObjectQuery 不會提供另一種使用方法,以作為其參數的實體 SQL 程式碼片段創建查詢的方式。

但與字串運算式中,有沒有強類型和查詢運算式不能得到解決,直到運行時,這意味著您不會在此之前發現問題。(請注意您可以使用不可或缺的 LINQPad — — 發現在linqpad.net— — 測試實體 SQL 以及 LINQ to 實體,外面的 Visual Studio。)那麼為什麼會有人想使用實體 SQL?

有很多原因。

讓我們開始用您的代碼中的語言。LINQ 是 C# 和 Visual Basic 的一部分。有 F # LINQ 提供的電源包。如果您在任何其他代碼。網路語言,您不能使用 LINQ。但是,您仍可以使用實體 SQL 來表示查詢。我還發現實體 SQL 有用構建複雜搜索實用程式在應用程式中。LINQ 是可組合,但在某一時刻,就只是很容易,只需建立一個字串。

您還可以在連接和命令與實體 SQL 運算式一起使用的 EF 執行較低級別的查詢。此路徑返回流的資料,是偉大的報告或移動資料。

查詢、 代碼生成和上下文選項

雖然建議使用 LINQ to 實體作為您的預設查詢策略,你見過為什麼您可能要在邊緣情況下利用實體 SQL 的原因。這是我做什麼,我推薦給用戶端,和我總是快樂的行使我不經常使用的實體 SQL 排骨的藉口。在 MSDN 上的文檔是非常全面的學習如何生成實體 SQL 運算式。但除此之外,一些老的博客文章從外匯基金團隊和我的書,"程式設計實體框架"(O'Reilly 媒體,2010年),我不知道許多資源學習語法中的一章。

代碼生成上,使用 EntityObjects 如果您正在編寫簡單應用程式,並且希望只是工作的事情是一個好的策略。但是,如果您正在構建要有持續性無知類應用程式,使用單元測試並按照分離關注點,那就是 EF 波蘇支援成立的路徑。即使這樣,你有一些使用純物件將需要一點額外注意編碼或利用代理的生成會讓 EF 做小干擾其工作時的靈活性。

EF 4.1 將多一項選擇添加到代碼生成,這 ObjectContext 或 DbContext 管理您 POCO 類之間進行選擇。許多開發人員跳轉到 DbContext,因為它是簡單的 API 來處理。如果您需要更精細的級別的交互更改跟蹤,控制或願意利用現有的代碼或知識的 ObjectContext,您可以繼續使用 ObjectContext 作為基地為您的上下文。

Julie Lerman  是 Microsoft MVP。淨的導師和顧問住在山上的佛蒙特。您可以找到她提出對資料的訪問和其他 Microsoft。使用者組和世界各地的會議的淨主題。在她的博客thedatafarm.com/blog是備受推崇的書,"程式設計實體框架"(O'Reilly 媒體,2010年) 的作者。跟她在 Twitter 上twitter.com/julielerman

感謝至下列技術專家檢閱這份文件:Tim Laverty