本文章是由機器翻譯。

資料點

Entity Framework Code First 與 DbContext 常見問題集

Julie Lerman

 


這個月,我想分享常見問題有關代碼第一次和 DbContext 中的實體框架 4.2 的問題的答案。要最大限度的空間,我會指向額外資源,您可以在其中找到我所提供的材料的補充的詳細的資訊。

將代碼第一次和 DbContext 將添加到。NET 框架?

號代碼的第一次和 DbContext 將從 Microsoft 的分別進行分佈。NET 框架釋放週期,允許實體框架團隊發佈的更新,而無需等待下一次官方發佈準備就緒。NET 框架。第一次代碼,DbContext API EntityFramework.dll 程式集,您可以向您的專案使用 NuGet 動態添加的一部分。在 Visual Studio 中安裝 NuGet 副檔名為您提供讓您對 EntityFramework.dll 的引用添加到專案的庫套裝軟體管理器。圖 1 顯示的 EntityFramework 套裝軟體 (目前 NuGet 包庫中最受歡迎下載) 在 Visual Studio 庫包管理器。

圖 1 首先安裝代碼和入到專案中通過 EntityFramework.dll DbContext

你可以閱讀更多關於實體框架和為什麼他們決定專注于使用 NuGet 部署某些類型的外部特徵特性的發佈團隊的計畫。在其 2011 年 10 月的博客,"如何我們談論關於 EF 和及其未來版本"中網 Api (bit.ly/owoWgn)。

您可以篩選與包含相關的資料嗎?

號包含方法允許您執行針對實體資料模型的查詢時,熱切地載入相關的資料。不幸的是,您可以檢索渴望載入相關資料的唯一一個完整的集。這也是真正為延緩載入和所有,但一種情況,進行顯式載入。該單個案例:當您顯式載入通過更改跟蹤器 API 時,您可以應用一種查詢方法後, 跟一個 Where 篩選:

context.Entry(personInstance)
  .Collection(p => p.Aliases)
  .Query()
  .Where(a=>a.FirstName == "Natasha")
  .Load();

但很明顯,你不能這樣的渴望與包含載入。

這是包括一直以來的實體框架中的第一版。NET 框架 3.5。 如果要合併渴望載入篩選,考慮使用的預測。 你可以閱讀更多關於這在 2011 年 6 月資料點列中,"Demystifying 實體框架戰略:載入相關資料,"在 msdn.microsoft.com/magazine/hh205756。 我也在寫博客上的話題,"使用預測和存儲庫到假過濾渴望負荷," bit.ly/uZdnxy

如何使用和一般包括與?

與 ObjectContext,包括使用的唯一方法是通過傳入一個字串來表示熱切地載入的導航屬性。 例如,如果您有一類的屬性,樹,這是 ICollection <Tree>,它的路你就會查詢他們的樹木,像這樣的道路:

context.Roads.Include("Trees")

許多開發人員已創建他們自己的擴展方法,讓他們轉而使用強類型的運算式:

context.Roads.Include(r => r.Trees)

DbContext API 現在內置包括 lambda 運算式中使用的能力。 你會發現關於 DbContext API 的一部分 6 的亞瑟維氏的精彩 12 部分博客系列中的一個示例 (bit.ly/wgI5zW)。 您嘗試使用此功能可能未獲成功,但是 — — 如是我的。 我不得不放下我的自尊心,問某人在團隊如何獲得 lambda 支援。 事實證明在 EntityFramework.dll 的引用,您需要使用指令 (或進口的 Visual Basic) 為 System.Data.Entity,您試圖使用包含帶有 lambda 的代碼檔中。 如果要擴展載入一個集合,使用和一般的關係的多個級別上的渴望,你要把額外的選擇方法。 例如,如果您的類樹有 ICollection <Leaf> 和你想要到渴望負荷隨樹的葉子,看起來像這樣的字串表示形式:

context.Roads.Include("Trees.Leaves")

但是,lambda 依賴額外的邏輯,以提供下一級別的關係。 這裡是會選擇道路與樹木和它們的葉子一起使用的語法:

context.Roads.Include(r => r.Trees.Select(t => t.Leaves))

我不能說說使用的包含多個級別而不添加提醒人們,使用包含,更為複雜和降級可能成為您的 SQL 查詢載入您嘗試渴望更多的關係。 我總是強烈推薦性能分析生成的實體框架 (EF) 的 SQL。 事實上,2010 年 12 月的資料點列演示使用 EF 時,設定檔資料庫的各種方式。

我很瞭解如果您使用的 ObjectContext API,EntityFramework.dll,加上使用指令的 System.Data.Entity 的引用將會讓你使用和一般包括在這裡,也吃驚。

我要等待。NET 框架 4.5,如果我想首先使用代碼,WCF 資料服務?

為創建和使用 WCF 的資料服務中有兩個程式集。NET 框架 4:System.Data.Services.dll 和 System.Data.Services.Client.dll。 如果您嘗試使用這些與 DbContext 和代碼第一類,他們不會工作框。 是 DbContext,不代碼首先的問題。 DbContext 不存在時,這些程式集被修建,所以他們並不理解。 在 2011 年 3 月,微軟發佈了社區技術預覽 (CTP) 包含知道如何使用 DbContext 的固定向上元件 (Microsoft.Data.Services.dll 和 Microsoft.Data.Services.Client.dll)。 所以你要做的一切是替換預設的程式集,這些新的程式集,並在您的資料服務,指定 DataServiceProtocolVersion V3,而不是 V2。 下麵是一個簡單的資料服務可能類似揭露繼承自 DbContext 的上下文 (PersonModelContext) 的一個示例:

public class DataService : DataService<PersonModelContext>
  {
    public static void InitializeService(DataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("People", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}

此解決方案的問題是新的程式集是只簽注而不是為生產目的。 你將不得不等待到製造 (RTM) 版本的資料服務,以便能夠在生產中使用它們的下一次發佈。

但可以使用與 DbContext。NET 框架 4 System.Data.Services 的程式集。 CTP 程式集存在只是為了説明你避免編寫額外的代碼。 您需要做的全部是訪問底層的 ObjectContext,它支援 DbContext 和提供的服務。 2010 年 7 月,羅恩 · 米勒,一個重要的角色,在後面的代碼第一次,微軟表明這一篇博文中"EF CTP4 提示 & 技巧:在 DbContext 上的 WCF 資料服務"(bit.ly/c2EA0l)。 該博客是寫早期預覽的 DbContext,所以已經更新了他工作與 DbContext 類中使用 PersonModelContext,一個簡單的模型公開一個 DbSet 人類的實體框架 4.2 版本的示例。 在圖 2 中顯示的上下文和類。

圖 2 簡單 DbContext 和資料服務所使用的類

public class PersonModelContext : DbContext
{
  public DbSet<Person> People { get; set; }
}
public class Person
{
  public int PersonId { get; set; }
  [MaxLength(10)]
  public string IdentityCardNumber { get; set; }
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

然後定義資料服務工作與 ObjectContext,而不是專門為從 DbContext 派生的 PersonModelContext。 然後,通過重寫資料服務 CreateData­源方法,您可以公開 ObjectContext 是 PersonModelContext,從而提供所需的 ObjectContext 的服務,如圖 3 所示的基礎。

圖 3 A WCF 資料使用服務,與 DbContext。NET 框架 4 服務 Api

public class DataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("People", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =
      DataServiceProtocolVersion.V2;
  }
  protected override ObjectContext CreateDataSource()
  {
    var dbContext = new PersonModelContext();
    var oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    return oContext;
  }
}

因為我想著重提供 ObjectContext,這是代碼的您可能擁有 WCF 資料服務中的簡化的視圖。

這種方法的缺點是,您不能使用 DbContext 功能如驗證 (我的 2011 年 12 月的資料點列"處理實體框架驗證在 WCF 資料服務"中所述,在 msdn.microsoft.com/magazine/hh580732) 因為該服務的設計目的是與 ObjectContext 工作。

應該使用資料的注釋或流利的 API 對於代碼的第一個配置嗎?

被問及這個問題很多。 要理解答案,最好先瞭解這兩個選項之間的高級別差異。

代碼首先擴展資料的注釋,都已經部分。NET 框架 4 System.ComponentModel.DataAnnotations 命名空間。 除了,如 ValidationAttributes 的批註 (必填,StringLength,規則運算式),實體框架添加指定資料庫映射 (例如,列、 表和時間戳記) 或其他特定模型的功能,例如複雜類型的屬性。 批註是簡單地在類中,人的班,在圖 2 中所示。

有一些可能的缺點,配置您的類的代碼第一次使用資料的注釋。 一個是你可能不會將與持久性相關的邏輯添加到您的業務類的風扇。 如果你問你自己,"不會資料庫列的名稱必須做什麼與我的域模型?"你可能不想使用的資料的注釋。 另一個是這些映射要求您以參考 EntityFramework.dll 從包含您的業務類的程式集。 (這而更改。NET 框架 4.5,將 EF 相關資料批註的所有權。)那,也可能不是你想做的尤其是如果你將應用程式分發跨層的東西。 此外,代碼的第一個資料批註不要暴露配置,可以使用代碼第一次應用的完整的陣容。 僅使用流利的 API,可以實現一些配置,例如那些指定的每個層次結構表 (TPH) 映射的特定詳細資訊。

我給開發商的建議是,選擇你喜歡的樣式。 如果您願意讓您實體框架 DbContext 所表示的配置,然後使用流利的 API。 如果您喜歡簡單的應用屬性並不介意有您的類中的代碼第一個映射邏輯,使用的資料的注釋。 如果您選擇要使用的資料的注釋和遇到過一種配置,可以表示只有流利的 API,然後流利地添加該配置和使用的資料的注釋和流利的配置組合。

可以使用代碼首先與現有資料庫嗎?

絕對 ! 雖然代碼第一次的預設行為是 (有益) 為您創建一個資料庫,但可以指向一個現有的資料庫與您自己的連接字串和有代碼首次使用的。 有一些內部代碼首,可讓您以程式設計方式指定資料庫和功能。 例如,您可以重載 DbContext 構造函數與資料庫名稱或資料庫連接字串。 你可以還指定和甚至自訂 DbContext ConnectionFactory 類型 (例如,SqlConnectionFactory)。

您需要確保代碼第一公約加上準確地添加任何配置代表您的類將映射到現有資料庫的方式。 微軟已經在一種工具,可以將資料庫進行反向工程到類加代碼第一口流利的配置,可以提供很好的頭開始。 您可以瞭解有關此工具在我的 2011 年 5 月的博客帖子,"快速看在逆向工程師 DB 到代碼第一類"(bit.ly/lHJ2Or)。

當指定的位置,避免架構驗證和 DbContext 不會預設情況下,與代碼第一次的資料庫初始化。 您可以完全禁用此功能,通過代碼第一次資料庫初始化:

Database.SetInitializer<MyContext>(null)

你會找到更多關於這一主題在 MSDN 資料開發人員中心文章和視頻,"資料庫初始值設定項實體框架 4.1"(msdn.microsoft.com/data/hh272552)。有關使用 ConnectionFactory 類和 DbContext 重載的詳細示例,請確保檢查"程式設計實體框架:代碼第一次"(O'Reilly 介質,2011年),我從代碼第一團隊合著羅恩 · 米勒的一本書。

其他資源

有很多地方,瞭解有關使用代碼第一次和 DbContext。在實體框架團隊博客 blogs.msdn.com/adonet 充滿突飛猛進和例子。有些團隊成員的博客,例如羅恩 · 米勒 (romiller.com) 和亞瑟維氏的 (blog.oneunicorn.com/author/ajcvickers),閱讀有關的偉大的地方高級技術。MSDN 論壇和 StackOverflow.com 繼續讀取執行緒或您自己問的好地方。米勒和我最近寫了兩個短書,上述"程式設計實體框架:代碼第一"和"程式設計實體框架:DbContext"(O'Reilly 介質,2012年)。你可以得到這些列印或數位格式。

有無需苦苦掙扎試圖找出關於你自己的事情。

Julie Lerman 是 Microsoft MVP。淨的導師和顧問住在佛蒙特州的丘陵。您可以查找資料訪問和其它微軟對她提出。使用者組和世界各地的會議的淨主題。在她的博客 thedatafarm.com/blog 和"程式設計實體框架"的作者是 (2010 年) 和"程式設計實體框架:代碼第一次"(2011 年),兩者都從 O'Reilly 媒體。跟著她在 Twitter 上 twitter.com/julielerman

多虧了以下的技術專家審查這篇文章:Mike Flasko 和  Diego Vega