2016 年 7 月

第 31 卷,第 7 期

本文章是由機器翻譯。

技術最前線 - Code First、持續性及領域模型的簡介

Dino Esposito | 2016 年 7 月

Dino Esposito程式碼第一次是一種功能,您會發現在 Entity Framework (EF),可讓您使用一般的.NET 類別的模型資料庫資料表。坦白說,我認為第一個程式碼的名稱是有點誤導之虞,但實際上執行的工作會更清楚。程式碼會先配置所使用的資料庫結構,並提供如何使用預存的資料具有物件導向 API。

引進 EF4.1 的第一個程式碼包含設定透過 EF6 — 只是其中一種方法可以用來透過 C# 或 Visual Basic 類別您資料庫的模型。直到 ef6 之後,您也可以使用 Visual Studio 設計工具推斷的資料庫結構描述、 將它儲存到副檔名為 EDMX XML 檔案和程式碼中建立使用臨機操作的類別。Visual Studio 設計工具也可讓您建立稍後用來建立實體資料庫的抽象模型。

若要讓長話短說,直到有 EF6 已執行相同的東西,而是 EDMX 方法的兩種 — 雖然功能 — 是比其他多個問題。基於這個理由,即將推出 EF7 中止執行 EDMX 支援。

多年來,Code First 已關聯與 Domain-Driven 設計 (DDD),這可能會促成 Code First 和 EDMX 不完全是兩種方式執行相同的一般概念。在本專欄中,我提供一個架構的觀點來看,Code first,網域模型的領域和領域的持續性模型之間繪製一條線。程式碼第一次,以及 LINQ,使用舊的夢想,大部分的開發人員︰ 它會隱藏複雜的物件導向的外貌後面 (資料表、 索引、 條件約束) 的資料存取,並可視為您從未該物件為導向的資料定義語言。 

歷史背景

同時使用關聯式資料庫,您播放 SQL 語言的規則。而撰寫的應用程式,您播放所選擇的程式設計語言的規則而。因此,來橋接物件導向所需的抽象層,或程序 — 性質的最上層的程式設計語言,使用 SQL 語言。在 Microsoft.NET Framework 中,這個抽象層是 ADO.NET 架構。

ADO.NET 是相當精簡的抽象層,也就是它只提供.NET 程式碼以將 SQL 命令的物件。ADO.NET 並不對應傳送,或從資料庫擷取到臨機操作的物件導向的資料結構的任何資料。在 ADO.NET 中,完全與周圍的.NET Framework 中,合併工具來取得資料,但都是一般資料。

十年前,相關物件/關聯式對應工具 (O/RM) 架構出現的好時機。O/RM 架構會將類別的屬性對應至資料表的資料行。如此一來,它會實作一大堆設計模式,例如資料對應程式、 工作單位和查詢物件。O/RM 架構也會保留在內部一組對應規則和目標資料庫的結構描述資訊。這是具體和有形必須在某處,並以某種方式儲存的資訊。NHibernate — 第一個曾經 O/RM.NET 空間中,將該資訊儲存為 XML 檔案。EF 一開始採用同樣的方法與 EDMX 檔案,並加入不錯的設計工具來管理從 Visual Studio 內。程式碼首先會對應至資料行和資料表透過屬性或 fluent (和更豐富) API 的類別屬性。

出現了幾個月前的部落格文章,EF 小組解釋清楚的方式進行程式碼第一次只支援的方法將資料模型儲存在 EF7 背後的動機。(您可以閱讀完整故事在 bit.ly/1sLM3Ur。) 在文章中,運算式 」 程式碼為基礎的模型 」 用做為程式碼第一次真正的用途更說明名稱。我更加深信不疑。

簡而言之 DDD

DDD 是一開始設計成一組規則來控制修訂版複雜 (也就是大量的商務規則和實體) 層級有系統地套用的軟體開發方法。雖然 DDD 大展身手至少幾百個規則和實體的非常大型系統中,它會有很多值的開發人員和架構設計人員在更簡單的案例中。總而言之,沒有理由套用的 DDD 幾乎每一個軟體專案中的某些部分。DDD 有價值的任何專案中的部分是策略性的設計,且會集中在應用程式的一些知名的方法︰ 無所不在的語言,繫結內容和內容的對應。這些分析模式也具備這不是實際的類別與資料庫資料表所得到的最終的應用程式中使用即使使用它們的終極目標是更有效率地撰寫程式碼。DDD 策略性的設計模式的目標是分析商務網域和構想產生系統的最上層的架構。[圖 1 提供可能的最上層架構,電子商務解決方案。每個區塊則代表在分析期間所識別,並加速開發導入繫結的內容。

範例與繫結內容的最上層架構
[圖 1 具有已繫結的內容範例最上層架構

每個繫結的內容,從您的分析有它自己的商務語言、 其本身 (包括技術) 的軟體架構和自己的其他繫結內容的關聯性集合。每個繫結的內容可能則會使用實作的軟體架構,最適合的給定數字的數目和技術的小組參與、 預算和時間限制,再加上任何其他專案關係人的考量,例如與現有的軟體授權、 成本、 專業知識、 原則等等。DDD 還可以建置繫結的內容,真是了不起的真正有效的方式清除任何建議︰ 多層式的架構。

分層架構中的網域模型

[圖 2 提供分層架構 gist。它有四種階層 — 範圍從簡報到基礎結構 — 與應用程式層和中間網域層級。簡單地說,它是已知的三層式架構的通用的形式 — 簡報、 商務、 資料,與使用案例之間有明確的分隔變更與您考慮在簡報中的使用案例的邏輯和網域邏輯的既有的特定方式的商務應用程式,且所有共用的使用案例和簡報層級。

分層架構的結構描述
[圖 2 分層架構的結構描述

基礎結構層級包含任何擁有所需的實作和支援的使用案例,並保存網域實體的狀態。基礎結構層,因此,包括知道連接字串以連接到資料庫的元件。

DDD 方法的核心是概念的 「 網域模型 」。 非常簡單,網域模型是您建立可充分表示商務領域的軟體模型。換句話說,它是如何運用軟體,可讓您處理您所面臨的網域。一般而言,網域模型會填入實體、 事件和值的物件,和部份實體和值的物件一起運作來構成 indissoluble 的單位。DDD 會呼叫 「 彙總 」 和彙總的根是彙總的根。持續性的彙總的根層級發生和彙總根通常也負責保存所有其他實體與值物件的彙總。

如何編寫彙總的實體和實值型別? 這取決於您使用的程式設計範例。大部分下,網域模型是情況的物件導向的模型的實體類別與屬性,而方法和值的物件是情況的不可變的資料結構。使用函式的語言和不可變的資料結構是一個選項,不過,至少在某些類型的商務領域。

程式碼第一次是完全與資料存取工作的效能相關的具象技術。最 characterizing 層面的第一個程式碼是使用類別來代表基礎結構描述的資料表和應用程式所使用的資料。應用程式的資料相同的保存關聯式資料表透過應用程式所使用的資料? 或者,您也可以要求另一種方式,是一組程式碼第一次使用應用程式的網域模型相同對應關聯式資料庫中的資料表的類別? 嗯,大部分是我想不會,但是談到的軟體架構,如往常,而定。

分層架構中的網域模型

程式碼第一次是有時聯 DDD 因為這樣可以透過類別的應用程式的資料模型。雖然有時候多個可以接受一組類別,以處理這兩個商務邏輯的網域和持續性的問題,一般條款網域模型和持續性模型,則不同。網域模型是用來表示系統的網域邏輯和實作的商務規則的軟體模型。它可能是物件導向的模型,以及功能的模型或甚至超出協助程式類別所公開的靜態方法的一般集合。

您將網域模型的持續性考量,而您更加專注於商業項沒有 (和使用方式) 於網域模型的設計中的資料包含並管理 DDD 的點。行為為中心的方法可以有效地使用程式碼來處理層級中斷修訂版複雜層級。我們來看一個簡單的範例,運動相符項目中所示 [圖 3

行為與網域模型的實體中的資料
[圖 3 行為 vs。網域模型的實體中的資料

若要表示比對實體的計分系統內容中的行為,您將模型動作,例如開始、 完成、 目標、 逾時和其他任何合理的特定案例。這些方法會實作所有的商務規則,並確保只有動作與目前實體的狀態一致以程式設計方式執行。比方說,此方法的目標會擲回如果因為逾時而目前處於暫停狀態的相符項目執行個體上叫用。比對實體的內部狀態包含所有這些屬性,您會通常關聯單純的關聯式模型中的這類實體之處在於這些屬性是唯讀和內部才更新,透過方法。

並非所有您可能必須在網域模型中的類別必須 persisted 和持續性可能會包含所有屬性或只是少數。因此第一個程式碼不是網域模型的一般情況下,但是它的 API,將屬性對應至資料表資料行可以用來保存需要保存在網域模型中的類別。如此一來,您有單一網域包含商務和持續性模型需要。

私用 Setter 的問題

在網域模型檢視方塊中,您只使用實體下列商業工作流程由網域專家所述。回頭看比對分數範例中,您可能無法與商務規則,以程式設計方式設定比對或分數的狀態一致。狀態和分數,事實上,變更工作流程進展。同樣地,您不會有預設無參數建構函式,因為它會傳回符合實體缺乏一些重要資訊,例如名稱的遊戲團隊以及合理地繫結的比對競賽的識別碼。然而,如果您使用單一模型的商務和持續性,無參數建構函式是必要項,否則,EF 將無法查詢後傳回之型別的執行個體。

但是還有其他考量。當 EF 執行查詢,並傳回相符項目類別的執行個體時,它必須以一致的狀態傳回的執行個體儲存在資料庫中的資訊存取的所有屬性 setter。合法的此項需求 EF 衝突的網域模型的設計規則。更一般情況下,強制必須存在成實體網域模型的狀態和大部分的方式它必須是情況的內部和公開可用透過程式碼層。這是構成,以及網域的網域層級的網域服務的目的 [圖 2。如果您使用第一個程式碼,您可以達到相同只要標示為非公用的 setter (內部、 受保護或甚至是私用),並新增相同的非公用可見性的預設建構函式。EF 仍然會發現 (透過反映) 的方式來存取私用成員,並強制狀態,但網域 API 的公用用戶端不會。嗯,才能使用反映本身。

總結

不尋常瀏覽網站並尋找第一個程式碼置於 DDD 關聯性的文件。程式碼第一次的重點明確對應到一組資料表的物件導向模型的持續性。網域模型在概念上來說,是完全另一項,而且甚至不同的圖層。不過,由於一些特定的程式碼的第一個 API 功能 — 處理私用 setter 和建構函式,在某些情況下就可以使用單一的物件導向模型,其中包含行為和商務規則,並可以輕鬆地保存至關聯式資料庫。


Dino Esposito 是每個 「 Microsoft.NET:  架構的企業應用程式 」 (Microsoft Press,2014年) 和 [使用 ASP.NET 最新 Web 應用程式] (Microsoft Press,2016年)。.NET 和 Android 平台在 JetBrains,並在世界各地的產業活動的技術推廣人員 Esposito 分享軟體的願景 software2cents@wordpress.com 和 Twitter: @despos

感謝以下的微軟技術專家對本文的審閱: 喬恩 · Arne Saeteras