本文章是由機器翻譯。

Entity Framework

Entity Framework 6:忍者版

Julie Lerman

最新主要發行版本的Entity Framework、 EF6、 Microsoft 物件-關係映射 (ORM) 工具已達到了新的高度的"忍者縮影。它不再是國家表哥長建立.NET ORM 工具。EF 長大了,和它贏得前頑固派。

Entity Framework已通過斷斷續續的起步階段,在那裡它開始作為一種工具的重點水域資料庫開發人員 — — 和啟發.NET 社區內的敏捷開發者的憤怒。它學會如何去開的應用程式的開發,並轉移到平原舊 CLR 物件 (思卡爾) 模型,不剝奪資料集中開發人員的情況下啟用域集中的測試和軟體發展。它解決性能問題和眾多關注生成代碼的品質,並贏得了許多資料庫管理員 (Dba) 一路走來。

從 EF 4.1 開始,微軟承認 EF 所需和通過引入 DbCoNtext API 簡化訪問其功能的複雜性。同時,因為不是每個人都想要使用設計器或生成的代碼,它提供構建您自己的代碼模型的能力。一路走來,是不是關於功能、 語法、 代碼或性能的另一個重大變化。EF 團隊變得更加透明和互動與社區的使用者,和它開始提供功能釋放更多流利而不是將它們綁定到 Microsoft.NET 框架。這導致兩個進展 EF5 被釋放在 2012 年後。第一,所有的Entity FrameworkApi 提取從.NET 框架和結合的團隊也工作的帶外功能 Api。第二,整個發展努力搬到開放源碼的模型。公開上已開發了 EF6 entityframework.codeplex.com。不僅你能看到,團隊通過會議筆記、 簽和可下載的夜間生成,在做什麼,你也可以貢獻源到 EF6 (雖然與 EF 隊的全面監督)。

請記住 EF6 是演變而來,不是革命。你已經知道的關於 EF 幾乎一切保持不變,你如何生成Entity Framework模型和如何在應用程式中使用 EF 等。EF6 進展 ORM,但改變不了它從根本上是如何工作。如果你在學習 EF 投資,這種投資繼續還清。EF6 並不是沒有某些重大更改 — — 但這些僅限於一些很容易處理,如果你準備好的命名空間改動。我會指向你在結束了這一條的指南的資源。

我認為 EF6 中的功能,有幾類:

  1. 來免費的功能:這些都是核心部分的功能。你甚至不需要知道他們是來從中受益,更不用學習任何新的編碼。這一組包括由一個重寫的視圖生成引擎和查詢編譯修改,由 DbCoNtext 能夠使用已打開的連接和已更改的資料庫設置為創建的Entity Framework的SQL Server資料庫授予的穩定性帶來的性能增益等功能。
  2. 級別設置的功能:一項主要的改進是代碼第一現在支援映射到預存程序,在設計器中創建的模型得到的東西。此功能已在通道 9 錄影帶了不少的覆蓋範圍 (例如在一個 bit.ly/16wL8fz) 和在 CodePlex 網站上的詳細規格,所以我不會重複此文章中的資訊。
  3. 更有趣的是另一種變化。如前所述,與 EF6,已從.NET 框架 ; 提取了 EF Api 他們是現在完全封裝的 NuGet 包中。這意味著引入與 EF5,某些功能 — — 例如,枚舉和空間資料支援和改進的性能 — — 不再依賴于.NET 4.5。所以如果你使用的.NET 4with EF6,你可以最後受益的那些功能。
  4. 我還將在這一類別包括的 EF 設計器。它一直到 2013年版,搬出Visual Studio,相反向Visual Studio提供的作為副檔名。為 EF6,作為擴展設計器是一個巨大的獎金。展望未來,團隊將能夠將功能直接添加到設計器中,包括那些目前提供的Entity Framework電動工具。分離Visual Studio設計器允許 Microsoft 船舶Visual Studio2012年,以及Visual Studio2013 EF6 模具。
  5. 忍者功能:這些是你渴望已久自從你過去的 EF 基本應用程式範例的功能。在 EF6 中有許多這種功能:支援非同步查詢和保存的自訂代碼第一項公約,返回更多的可擴充性,使用新的 DbConfiguration 類型 (其中依賴低級 EF6 IDbDependency­衝突解決程式),嘲笑在單位支援測試、 參差不齊的連接,和更多的可配置重試次數。你不需要認證的忍者可以使用這些功能 — — 但你肯定會感覺像一個當你做 !

我也想要突出顯示一個特殊的類別:來自社區成員的 EF6 捐款。島宇內利亞添加 DbSet.Add­系列和 RemoveRange,多元化和方便的 DbChangeTracker.HasChanges 方法的自訂功能。他還在其他的 EF 以後的反覆運算的超酷功能。埃裡克 · 詹森、SQL Server緊湊 (SQLCE) 最有價值球員,促進了 SQLCeFunctions,類似于在LINQ中使用SQL Server功能實體查詢到 SqlFunctions。EF 視圖生成的大大提高的速度 — — 最具戲劇性的龐大、 複雜模型 — — 阿裡禮薩 · Haghshenas 和名為 VSavenkov 的 CodePlex 成員的推動。它也是可能現在來定義自訂遷移操作,由於 Iñaki Elcoro,aka iceclow CodePlex 上。(榮恩Miller的 EF 團隊寫一些博客帖子的關於此功能 ; 第一個是在 bit.ly/ZBU0w1.)派遣的完整清單可以在發現中的團隊博客文章,"EF6 RTM 可用的" bit.ly/1gmDE6D

這篇文章,就會鑽進的一些較少宣傳的主題,和你指向現有資源,以瞭解有關其他詳細資訊。

版本歷程記錄頁上 MSDN 資料開發人員中心 (bit.ly/1gCT0nz) 列出的所有功能,每個都有一個句子或兩個細節,有些是更多的資訊的連結。

其工作原理:改進性能和穩定性

性能是一個軟體專案的許多的禍根,一直有大量性能的Entity Framework自其成立以來的批評。然而,每次反覆運算中 EF 在這一領域帶來了巨大的改進。

在性能上的最大阻力之一是上下文的涉及與第一次使用在應用程式進程的啟動時間。你可以做不少,但改善的啟動時間。希望你已經學會這些技巧從我自己以書面形式或其他資源的情況下,如對性能注意事項在 MSDN doc bit.ly/3D6AiC

一個常常阻礙了性能的啟動步驟是視圖恒­的映射的視圖,其中 EF 創建針對該實體的每個查詢到有關 SQL 設置在模型中。這些意見得到杠杆作為您的應用程式將運行,以便對某些查詢,EF 也不用工作了動態 SQL。視圖生成發生是否與 EF 設計器或代碼第一次,您將創建您的模型。可以預生成這些意見,並將其編譯到應用程式中以節省時間。

對於大型、 複雜的模型,視圖生成是特別是非常耗時的。EF6,戲劇性的是,提高速度,無論您預生成的視圖,還是讓這一切發生在運行時,經過了這一進程。注意是 EF 6.0.0 版中的 bug 釋放,阻礙了此功能,但它糾正在 EF 6.0.1 版,而在同一天發佈了和 (在寫作的時候),你會得到通過 NuGet 的缺省包。另外,EF 使用這些生成的視圖在運行時的方式已得到增強,提高查詢執行時間。對小型或簡單模型視圖生成永遠不是一個問題。但很多組織有數以百計的還包括繼承、 關係和其他併發症的實體模型。這些組織將大大受益于這種變化。

上另一個性能說明,請參閱有關使用 Ngen 針對Entity Framework集在宣佈博客中釋放的 EF6 在指導 bit.ly/1gmDE6D

更快的LINQ包含編譯 EF 團隊繼續調整如何創建查詢,並突出了團隊的一個變化是如何使用LINQ包含查詢的編譯。很明顯,它是改善了編譯過程的性能。生成的 SQL 並沒有改變,所以在資料庫中查詢的執行不受影響。

SQL Server資料庫創建 EF6 穩定性方面的改進之一有關創建資料庫。模型第一次和代碼第一次工作流可為您創建一個資料庫。如果該資料庫是SQL Server,EF 現在與對齊"最佳做法"對於SQL Server的資料庫,這是要設定資料庫的 READ_COMMITTED_SNAPSHOT 設置為 ON。這意味著預設情況下,該資料庫將創建的快照本身每次進行更改。將快照上執行查詢,而在實際的資料庫上執行更新。我寫了有關此功能的一個最近的博客文章,"是什麼,不管怎麼說 EF6 Read_Committed_Snapshot 交易支援嗎?"在 bit.ly/14FDpZI

重複使用打開的連接最後,一個令人沮喪的限制已被刪除:EF6 允許您在打開 DbConnection 上執行上下文調用。在過去,如果您顯式打開連接前執行 EF 命令,使用該連接,或者您試圖重新使用一個已打開的連接會由另一個上下文調用,與消息"實體連接可以只構造與封閉 DbConnection"引發異常,。現在,EF6 是更樂意讓你重新使用一個已打開的連接。

忍者增強功能

非同步支援 探討了少量的新功能 — — 非同步查詢,SaveChanges 和自訂項公約 — — 在"播放與 EF6 Alpha,"我 2013 年 3 月資料點列中 (msdn.microsoft.com/magazine/jj991973)。

非同步支援對LINQ查詢執行方法帶來的.NET 4.5 等待和非同步模式為 EF,給你 FirstAsync、 FirstOrDefaultAsync、 SingleAsync、 SingleOrDefaultAsync、 ToListAsync、 ForEachAsync 和更多。要查看完整清單,請查看 System.Data.Entity.QueryableExtensions。DbSet 獲得了 FindAsync 和 DbCoNtext 獲得了 SaveChangesAsync。自這一條,沒有太大改變了,所以你可以看看它要獲取更多詳細資訊。此外,Microsoft 創建了一些檢查和有趣的詳細的規格,你可以從我剛才提到的版本歷程記錄頁。

自訂代碼約定還寫了那篇文章中的自訂代碼第一公約 — — 另一個忍者的特點,確定。EF 團隊致力於此初始釋放的代碼第一次,但它打著釋放和團隊被迫將其擱置起來 — — 對許多開發人員感到失望。

假設你有你想要作為一般規則應用到您的實體或屬性的常見映射。現在你可以定義它作為一項公約,而不是不必指定單獨為每個實體或屬性的映射在你的模型,和它將一律適用。例如,如果您希望將每個字串屬性在您的資料庫中表示為 50 個字元,而不是無論預設您的資料庫提供程式使用,您可以指定此規則作為一項公約。公約 》 利用代碼第一 Fluent API,所以建設公約應感到熟悉如果你已經在這種方式配置映射:

modelBuilder.Properties<String>().Configure(p => p.HasMaxLength(50))

現在,在此模型中的每個字串將映射到資料庫列的 50 個字元。作為具有流利或注釋的配置,您可以指定為屬性或實體,約定,控制繼承映射。影響通過公約 》 的關係是由基於模型的各項公約處理較不共同和更複雜的任務。有關詳細資訊,請參閱 bit.ly/1gAqcMq。您還可以使用公約 》 作為資料注釋。為執行公約時代碼第一次建立其模型有一個層次結構。預設情況下,內置公約運行第一次和自訂項公約之後運行。但是,您可以強制自訂的公約 》,先于一項內置的公約。在簽出"自訂代碼第一個公約" bit.ly/14dg0CP 為例子。

連接恢復能力連接斷開而 EF 正試圖執行一個查詢或保存的更改,如果你現在有能力告訴 EF 重試。雖然刪除的連接可以是在公司的 intranet 上的問題,連接恢復能力已被證明是相當有用的説明連接到雲計算的應用程式。可以使用 IDbConnectionStrategy 配置重試次數。SQL Server提供程式附帶 EF 指定預設: SqlServer­ExecutionStrategy,有錯誤訊息,建議您調整戰略的瞬態連接由引發的異常。另一個,SqlAzureExecutionStrategy,被調諧到 Windows Azure SQL 資料庫的連接。

指定策略的最簡單方法是用新的 DbConfiguration 類,可以輕鬆地配置一個特定的資料庫提供程式的行為方式。以下告訴 EF 用於 SqlClient SQLAzureExecutionStrategy:

SetExecutionStrategy (SqlProviderServices.ProviderInvariantName,
  () => new SqlAzureExecutionStrategy());

連接策略可配置的不僅是你可以還創建您自己的以及暫停他們根據需要以程式設計的方式。EF 團隊成員Miller演示如何暫停在他的博客中的 bit.ly/14gPM1y

我測試了 SqlAzureExecutionStrategy 使用建議的另一個 EF 團隊成員,葛籣 · 康得倫把戲。要觸發這一戰略將查找特定的瞬態連接故障錯誤代碼,我用新的 EF6 命令截取功能來扔瞬態連接錯誤。然後我跑測試其輸出表明當我設置的執行策略時,查詢的重試五次後最初出現故障。有關此功能的開發人員說,他的公司已經目睹此功能的好處從我博客上有偉大的評論 (bit.ly/HaqMA0)。

也是一種有趣的演算法,以確保在不同的執行緒上的重試次數不在同一時間執行。

分享 DbTransactions 和 DbConnections 我希望你知道的現在,EF 始終使用 DbTransaction,預設情況下為向資料庫發出的調用。例如,當調用 SaveChanges,DbTransaction 被創建的第一個命令被發送到資料庫之前。EF 然後將發送所有必要插入、 更新和刪除命令到資料庫中,和最後提交的事務。如果一個命令失敗,所有先前執行的命令都將回滾。

你一直通過 TransactionScope 來包裝 EF 電話和任何其他調用 (不一定資料庫或 EF-相關),必須在同一事務中旋轉覆蓋該預設行為的能力。現在除了 EF6 讓負責資料庫的多個調用單個 DbTransaction。請注意你就會仍然需要使用 TransactionScope,如果你想要包括非資料庫內的事務或分散式的事務的電話到不同的資料庫的邏輯。

與 EF6 共用 DbTransactions 的關鍵是一種新的 BeginTransaction 方法返回一個引用到當前的 DbTransaction 和 UseTransaction 的一種方法。

此代碼演示的預設行為:

//code to create two new casinos, "casino1" & "casino2"
var context = new CasinoSlotsModel();
context.Casinos.AddRange(new[] { casino1, casino2 });
context.SaveChanges();
context.Database.ExecuteSqlCommand
  ("Update Casino.Casinos set rating= " +
 (int) casino.Rating)

我探測器顯示交易被用在每個上下文調用附近 — — 一個到 SaveChanges,觸發兩個插入和一個到 ExecuteSqlCommand,觸發更新 — — 所示圖 1


圖 1 命令從單獨的上下文調用裹在它們自己的事務

現在我會修改的代碼共用一個事務,環繞的 SaveChanges 和 ExecuteSqlCommand 的調用。我會使用新的 DbCoNtext.Database.BeginTransaction 來顯式具現化的 System.Data.Entity.DbCoNtextTransaction 和打開的連接,如有必要 (請的記住,有類似的命令的 DbCoNtext.Database.Connection,但返回 System.Data.Common.DbTransaction,不能由 EF 命令共用的):

using (var tx = context.Database.BeginTransaction()) {
  try  {
    context.SaveChanges();
    context.Database.ExecuteSqlCommand
      ("Update Casino.Casinos set rating= " +
      (int) casino.Rating);
    tx.Commit();
  }
  catch (Exception)  {
    tx.Rollback();
  }
}

你可以看到在圖 2 的所有命令都包裹在相同的事務中。


圖 2 從單個事務中的所有上下文調用命令

有另一種稱為 UseTransaction 的新功能。你可以旋轉了 DbTransaction 然後使用它為ADO.NET調用和,與 DbCoNtext.Database.UseTransaction,甚至從單獨的上下文實例在同一事務內執行 EF 調用。你可以看到一個示例在 bit.ly/1aEMIuX

它也是可以顯式地重複使用打開的連接,因為 EF 現在可以創建 EntityConnection (ObjectCoNtext 的東西做在背景中) 與一個已打開的連接。此外,一個上下文不會關閉它沒打開本身的連接。我寫了一個簡單的測試,在其中打開之前從上下文執行調用上下文的連接:

[TestMethod]
public void ContextCanCreateEntityConnectionWithOpenConnection()
{
  using (var context = new CasinoSlotsModel())
  {
    context.Database.Connection.Open();
    Assert.IsNotNull(context.Casinos.ToList());
  }
}

當執行 ToList 調用,DbCoNtext 將創建 ObjectCoNtext 實例反過來將創建 EntityConnection。 使用 EntityConnection 來打開 DbConnection,然後調用與返回的所有結果完成時關閉 DbConnection。 在 EF5 中運行此引發異常的原因 ("EntityConnection 可以只構造與封閉 DbConnection"),但它成功在 EF6 的行為變化。 此更改將允許您重複使用連接的情況下,你希望有更多的控制連接的狀態。 規格建議方案"(如"共用不能保證連接的狀態的元件之間的連接。

AddRange 和 RemoveRange 前面已提到,AddRange 和 RemoveRange 是社區成員利亞的捐款。 每個方法將作為其參數可枚舉的一個單一的實體類型。 在共用的 DbTransactions 節中的第一個代碼示例,使用 AddRange 過後在賭場實例的陣列:

context.Casinos.AddRange(new[] { casino1, casino2 });

這些方法執行添加或刪除單個物件一次,因為預設情況下,Entity Framework中添加和刪除的每個方法調用 DetectChanges 比快得多。使用範圍方法,您可以處理多個物件,而 DetectChanges 只調用一次,大大提高性能。測試這過使用五、 50、 500、 5000 和甚至 50,000 物件和,至少在我的方案,是對陣列的大小沒有限制 — — 而且很快就令人印象深刻 !請記住這一改進才是獲取要採取行動的物件上的上下文相關,並沒有軸承 SaveChanges。將調用 SaveChanges 仍然只是一個資料庫命令在執行一次。所以雖然到上下文,您可以快速添加 50,000 物件,你還是會單獨執行調用 SaveChanges 時的 50,000 插入命令 — — 也許不是你想要在實際的系統。

上的這一面,有長時間的討論有關實施的批量操作支援無需由 EF 跟蹤的物件 (bit.ly/16tMHw4),和對於批次處理操作,以便在對資料庫的單個調用中一起發送多個命令 (bit.ly/PegT17)。既不功能把它做成初始 EF6 版本中,但兩者都是重要的和確定要為將來的版本。

更少的干擾您的編碼風格在.NET 中,有可能要重寫 System.Object.Equals 方法來定義您的系統規則的平等。Entity Framework,但是,有其自己的方式確定的跟蹤的實體,平等的這依賴于身份。如果你已經覆蓋等於 (和方法,它等於是取決於 GetHashCode),你可以把Entity Framework的更改跟蹤行為絆倒。佩塔爾 · 喜事演示了這一問題非常明確地在他的博客在 bit.ly/GJcohQ。若要更正此問題,EF6 現在可以使用其自己的 Equals 和 GetHashCode 邏輯執行更改跟蹤任務,忽略任何自訂等於,GetHashCode 邏輯你可能有寫。但是,您仍然可以對您自己的自訂方法的顯式調用在您的域邏輯。這種方式,這兩種方法能和諧地生活。

如果你專注在圖表和集料,要嵌套在其他類型內的類型。但代碼第一個模型產生器並不能夠發現嵌套的類型來創建實體或模型中的複雜類型。圖 3 顯示巢狀型別的示例:位址。所以我已經嵌套它在賭場類中,仍會使用僅在賭場類型的位址。我還創建了位址作為 Domain-Driven 設計 (DDD) 值物件因為它不需要它自己的身分。(請參閱我的 2013 年 10 月資料點專欄,"編碼域-­驅動設計:提示部分 3,Data-Focused 開發"在 msdn.microsoft.com/magazine/dn451438 更多關於 DDD 值的物件.)

圖 3 我賭場類的嵌套的網址類別型

public class Casino()
{
  //...other Casino properties & logic
  public Address PhysicalAddress { get; set; }
  public Address MailingAddress { get; set; }
  public class Address:ValueObject<Address>
  {
    protected Address(){    }
    public Address(string streetOrPoBox, string city,
                   string state,string postalCode)
    { City = city;
      State = state;
      PostalCode = postalCode;
      StreetOrPoBox = streetOrPoBox; }
    public string StreetOrPoBox { get; private set; }
    public string City { get; private set; }
    public string State { get; private set; }
    public string PostalCode { get; private set; }
  }
}

EF 電動工具用於獲取視覺化表示形式的模型中,和在圖 4,顯示呈現使用 EF5 和 EF6 時,生成的賭場實體。EF5 沒認出的嵌套的類型,並不包括位址或依賴項屬性 (PhysicalAddress 和 MailingAddress) 在模型中。但 EF6 能夠檢測到嵌套的類型,您可以看到的位址欄位派代表在模型中。


圖 4 不同 EF5,EF6 看到嵌套的網址類別型,包括依賴屬性

啟用嵌套的類型相同的蓋子下更改也解決另一個問題。這是在同一個專案中有多個類型具有相同的名稱在不同的命名空間下提出的問題。以前,當 EF 從 EDMX 讀取中繼資料,並尋找匹配的類型的程式集,它沒注意到的命名空間。

由此而導致的問題的一個常見方案包括非 EF 表示的實體中包含的實體的模型專案相同的專案。所以我可能會從我的模型有該類的代碼生成 PokerTable:

namespace CasinoEntities
{
  public partial class PokerTable
  {
    public int Id { get; set; }
    public string Description { get; set; }
    public string SerialNo { get; set; }
  }
}

我也可能有此 DTO 類不是我的模型的一部分,但在同一專案中:

namespace Casino.DataTransferObjects
{
  public class PokerTable
  {
    public int Id { get; set; }
    public string Description { get; set; }
    public string SerialNo { get; set; }
  }
}

當專案目標 EF5,會生成專案時看到以下錯誤:

CLR 類型到EDM類型的映射是不明確的因為多個 CLR 類型匹配的EDM類型 'PokerTable'。以前發現的 CLR 類型 'MyDtos.PokerTable' 新發現 CLR 類型 'EDMXModel.DTOs.PokerTable'。

您將在設計時使用 EDMX 看到此錯誤。 與代碼第一,如果你有同樣的情形 — — 兩個匹配類具有相同名稱但不同的命名空間,以及那些之一類模型中 — — 你會看到這一問題在運行時,當模型產生器開始解釋的代碼第一個模型。

這個問題長期以來失望的原因之一。 我已經閱讀你的郵件,問我的電腦:"你沒看見不同的命名空間嗎? 你好嗎?"我也有的來自朋友、 用戶端和其他開發人員經歷過這一問題的電子郵件的集合。

EF6 將現在認識到的命名空間,允許這種情況。 你可以閱讀更多關於啟用這些博客中的兩個變化的內部張貼在亞瑟維氏由 bit.ly/Wi1rZA

移動到代碼的上下文配置有大量的設置,您可以應用在 app.config 或 web.config 檔來定義您的上下文應該如何工作。 例如,您可以指定資料庫初始化或遷移或預設的資料庫提供程式。 我的將這些資訊添加的方法往往已被覆制和粘貼因為這些設置太難,記住,涉及大量的字串。 現在,與 EF6,您可以聲明多個上下文配置中使用 DbConfiguration 類的代碼。 這在 3 月的資料點列中,發揮了,但遇到造成的競爭條件,該報告,並已修復的 bug。 所以我現在就會重新訪問 DbConfigurations (還提到為基於代碼配置)。 請注意有很多混淆的空間談時配置映射的代碼第一次與 DbMigrationConfigurations 與 DbConfiguration 設置用於定義當您更改您的模型資料庫移轉工作的方式。 DbConfiguration 被針對 DbCoNtext 設置。

DbConfiguration 取決於另一個超級忍者,EF6 的低級功能:依賴項決議,類似于ASP.NETMVC 和 Web API 中使用的 IDependencyResolver 的支援。 依賴項決議允許您使用服務定位器模式與控制反轉 (IoC) 模式在代碼中,允許 EF6 從實現公共介面的可用物件的層次結構中進行選擇。 在這種情況下根的介面是 IDbDependencyResolver。 雖然 EF6 包括 DbConfigurations,使它能夠發現並置於上下文設定優先權數,但有可能利用依賴項決議向 EF 以及添加新的功能。 我會堅持顯示的一些配置和您指向的功能規格在 bit.ly/QKtvCr IDbDependencyResolver 有關更多詳細資訊。

你可以使用 DbConfiguration 來指定熟悉的背景下規則,以及新的 EF6 的設置。 圖 5 顯示了一個示例配置類,包含 EF 將使用其預設行為的不同設置的主機。 請注意設置都放在類的建構函式。

圖 5 示例配置類

public class CustomDbConfiguration : DbConfiguration
{
  public CustomDbConfiguration()
  {
    SetDefaultConnectionFactory(new LocalDbConnectionFactory("v11.0"));
    SetDatabaseInitializer
      (new MigrateDatabaseToLatestVersion<CasinoSlotsModel, Configuration>());
    //SetDatabaseInitializer(new MyInitializer());
    SetExecutionStrategy("System.Data.SqlClient", 
      () => new SqlAzureExecutionStrategy());
    AddInterceptor(new NLogEfCommandInterceptor());
    SetPluralizationService(new CustomPluralizationService());
  }
}

SetDefaultConnectionFactory 排擠 DefaultConnection­廠標記您可能已經在使用在您的設定檔中的 entityframework 節。SetDatabaseInitializer 替換指定初始值設定項或遷移的配置,在設定檔中,或在應用程式啟動時。看兩個例子,雖然其中一個被注釋掉。SetExecutionStrategy 允許您指定該怎麼辦如果您的連接滴在 EF 查詢或其他執行命令。SetPluralizationService 公開 EF6 的另一個新功能:創建自訂 pluralizations 的能力。我有點更多解釋。

有一系列的影響範圍內與這些內置依賴項解析程式的其他方式。MSDN 文檔中,"IDbDepen­dencyResolver 服務"(bit.ly/13Aojso),列出了所有可用的 DbConfiguration 的衝突解決程式。依賴項決議也用於説明解決某些問題,當他們需要注入規則和邏輯上下文如何與提供程式進行交互時的提供程式編寫者。

查詢和命令攔截我沒有提到的 AddInterceptor CustomDbConfiguration 的使用。DbConfiguration 可以讓你做更多的比在 IDbDependencyResolvers 中推。EF6 的另一個新功能是攔截查詢和命令的能力。當攔截查詢和命令,你現在可以生成的 SQL,是關於獲得要發送到的資料庫和回來從這些命令的結果。您可以使用此資訊記錄的 SQL 命令或甚至修改它們並告訴 EF 要使用更新的命令。雖然我很喜歡玩這個功能,我會通過你指向它的一部分 3 的亞瑟維氏的三個部分的博客系列節省一些空間:"EF6 SQL 日誌記錄 — — 第 3 部分:截取構建基塊"(bit.ly/19om5du),其中已連結回第 1 部分 ("日誌簡單記錄") 和部分 2 ("更改內容/格式")。

自訂 EF 多元化在談到 EF 多元化的自訂功能之前, 我要確定你明白它的預設行為。EF 使用其內部多元化服務的三個任務:

  1. 在資料庫第一次,它確保實體有一個 singularized 的名稱。所以如果您的資料庫表的名稱是人,它將成為人在模型中。
  2. 在資料庫或模型第一次的 EF 設計器,它將創建基於機構名稱的多元化的 EntitySet 名稱 (DbSets 的基礎)。例如,該服務將確保人的實體的 EntitySet 名稱是人民。如果您創建使用資料庫第一次的模型,它不只利用表的名稱。
  3. 在代碼第一,在您顯式命名 DbSets,EF 使用服務來推斷的表名稱。如果你開始使用名為人的類,公約 》 將假定您的資料庫表命名的人。

該服務不會像拼寫詞典,您可以在其中提供的自訂拼寫文本清單工作。而它所使用的內部規則。除了偶爾異常情況 (我有有趣的機構名稱犀牛早期),該服務的最大問題是規則基於英語。

對於 EF6,利亞創建 IPluralizationService 介面,因此您可以添加您自己的邏輯。一旦你已經創建了自訂的服務,你可以將其插入與 DbConfiguration 中,如上文所示。

目前這種自訂僅適用于上面清單中的第三個案件:當代碼第一次推斷的表名稱。自初始 EF6 版本中,該自訂項不能應用到設計器。

有兩種方法,使用這項服務。您可以從開始的基本服務 — — 要麼 EnglishPluralizationService 在 EF 或別人已經建立的一個 — — 然後重寫 Singularize 或以複數形式表示的方法將添加您自己的規則。另外可以在 CustomPluralizationEntry 類中指定對單詞,並將該類附加到現有的服務。利亞演示 CustomPluralizationEntry 在他的博客 (bit.ly/161JrD6)。

尋找未來的資料點列在其中會添加規則 (不只是 word 對) 為複數形式,對代碼第一次資料庫映射的影響的示範的一個例子。

更多的代碼第一好吃的東西

有極少數的目標代碼第一,我尚未介紹的新功能 — — 特別是,代碼第一次遷移。由於篇幅的原因,我會在這裡突出他們並跟進一月 2014年資料點列中更加深入瞭解:

  • 若要創建可以檢查以查看其中已運行已經所以你可以修好從任何遷移點資料庫的遷移腳本的能力。
  • 對要為不同的資料庫供應商帳戶的 Migrations_History 表的更多控制。
  • 指定預設架構,而不是總是預設為 dbo 資料庫映射的能力。
  • 處理目標相同資料庫的不同 DbCoNtexts 的遷移能力。
  • 若要添加多個 EntityTypeConfigurations 在一次,而不是使用一行代碼為每個模型構建器的能力。

去得到忍者 !

在我看來,最重要的事情要記住約 EF6 是它將強大的功能添加到已經存在的事物在 EF 中。如果要移動的專案從 EF5 到 EF6,你應該知道的一些命名空間更改。團隊有詳細的指導,使這一舉動在 bit.ly/17eCB4U。此外,您應該相信有關使用 EF6,現在是當前穩定版本的Entity Framework,通過 NuGet 分發。即使你不打算使用任何忍者功能馬上,請記住本文中前面所述你仍然會受益更高的性能。我最興奮的忍者的功能,不過,和感激的向開發人員從的社會人士,以及已經添加到 EF6。

EF 將會繼續得到發展。雖然 EF6 的第一個版本恰好與釋放的Visual Studio2013年,EF 6.1 和版本之外,已在工程中。CodePlex 網站上,您可以按照他們的進展。

Julie Lerman* 是 Microsoft MVP、.NET 导师和顾问,住在佛蒙特州的山区。您可以在全球的用户组和会议中看到她对数据访问和其他 Microsoft .NET 主题的演示。她是《Programming Entity Framework》(2010) 以及“代码优先”版 (2011) 和 DbContext 版 (2012)(均出自 O’Reilly Media)的作者,博客网址为 thedatafarm.com/blog。通过她的 Twitter(网址为 twitter.com/julielerman)关注她,并在 juliel.me/PS-Videos 上观看其 Pluralsight 课程。*

衷心感谢以下技术专家对本文的审阅:榮恩Miller(Microsoft)