1

我願意將實體框架集成爲我的數據層。將POCO實體轉換爲商業實體

我跟着文章和產生使用本教程POCO實體:http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

我有我自己的業務對象。這是我的業務對象Brach:

public class Branch 
{ 
    public long BranchId { get; private set; } 
    public string BranchName { get; set; } 
    public string BranchCode { get; set; } 

    public Branch() { } 

    public void InsertBranch(Guid companyId) 
    { 
     using (var ctx = new Entities.Entities()) 
     { 
      var branch = new T_STF_BRANCH() //This is generated POCO object 
      { 
       company_id = companyId, 
       branch_name = BranchName, 
       branch_code = BranchCode 
      }; 
      ctx.T_STF_BRANCH.AddObject(branch); 
      ctx.SaveChanges(); 
     } 
    } 

    public static IList<Branch> GetBranchesList(Guid companyId, long? branchId, 
     string branchName) 
    { 
     using (var ctx = new Entities.Entities()) 
     { 
      var branchs = ctx.T_STF_BRANCH.Where(x => 
       x.is_deleted == false && 
       (branchId == null || x.branch_id == branchId) && 
       (branchName == null || x.branch_name.Contains(branchName))).ToList(); 
     } 
     //HERE I NEED SOMEHOW CONVERT THE POCO ENTITIES INTO MY BUSINESS ENTITIES... 
    } 
} 

我不知道如何將POCO實體轉換爲我的業務實體。
我應該從POCO轉換到POCO?

回答

10

恕我直言,這太複雜了。爲什麼你有POCO實體用於持久化,而單獨的對象用於處理加載到POCO實體中的數據?聽起來你的應用程序已經超過了體系結構。

ORM表示對象關係映射。它意味着關係世界和對象世界之間的映射。通常它也可以被翻譯爲數據庫和業務對象之間的映射。所以你應該使用你的POCO對象作爲你的業務對象。這就是使用POCO的全部意義。如果您不想將它們用作業務對象,則不需要它們,並且可以直接使用默認實體對象。

如果您想使用POCO作爲業務對象,只需讓EF爲您生成這些POCO並向每個定義您的方法的POCO添加部分類。

Btw。您的業​​務對象實際上看起來像實施Active Record pattern。如果你想使用這種模式,或許你應該檢查基於NHibernate的頂層的Windsor Active Record

編輯:

嘛。您可以使用您的類而不是生成的POCO實體。

一種方法是用EFv4和EDMX放棄,並檢查新EFv4.1 and its new fluent API(又名代碼優先)的映射。這是完整的單獨的問題,或者只是在SO上使用搜索。

你可以做到這一點與EDMX爲好。爲了完成這項工作,您必須遵循一些基本規則,因爲這是通過命名約定來完成的。因爲你已經有了類,您必須在EDMX文件中,這樣的概念模型是一樣的業務對象修改此:

  • 具有保存或加載必須在概念模型有實體每個業務對象
  • 實體必須與業務對象具有相同的名稱。此外,還必須正確設置在屬性窗口中的實體(抽象,訪問級別和基實體必須與在業務對象)
  • 每個存儲的屬性在業務對象必須在概念模型中的實體的屬性。再次,您必須正確設置每個屬性(getter和setter輔助功能,類型,可爲空等)。

EDMX由三層組成:

  • SSDL - 數據庫的描述。這幾乎總是生成的,你不能直接在設計器中修改它。
  • CSDL - 實體的描述,必須與您的業務對象。這是你在設計師修改的內容。您可以根據需要重命名這些字段。
  • MSL - SSDL和CSDL之間的映射。如果您在設計器中的任何實體上打開上下文菜單,您將看到表格映射。它將打開一個窗口,定義CSDL和SSDL之間的映射。

這些都是基本規則,但由於您已經擁有業務對象,您很可能會發現難以映射它的情況。最好的辦法就是要求這個具體問題。它很可能是關於一些複雜的屬性,導航屬性或繼承。

+0

+1我同意。我不認爲有必要將它們分開。當你開始加載關係等時,它也會給你帶來一些嚴重的痛苦,最終你會建立自己的延遲加載等,這是or/m的主要特性之一。 – Brook 2011-04-16 18:22:40

+0

@Ladislav Mrnka:我已經有了自己的商業實體。我的所有應用程序都是用它們寫的。所以我不能使用POCO對象作爲我的業務對象。另一方面,我的業務對象具有繼承性,它們是複雜的對象 - 與POCO不同。我不確定我可以用它們代替POCO。我會真正appriciate一個例子。 – Naor 2011-04-16 22:28:24

+0

@Naor:我編輯了我的答案。這對你來說很重要。您必須顯示具體問題,您不知道如何映射它以獲取樣本。 – 2011-04-16 23:10:36

1

這裏有一些可能性,如果我理解你是對的。

你有你的POCO實體代表你的數據庫中的表,你有一些業務類,甚至可能查看模型,你想從一個到另一個。

第一種可能性,在您的業務實體中,創建一個構造函數,將您的POCO實體作爲參數,然後設置每個屬性。

例如

public Branch (POCO poco) 
{ 
    Name = poco.Name; 
    Zip = poco.Zip; 
} 

另一種選擇是使用像AutoMapper

的工具它會幫助你自動地圖(因此而得名;))這兩個實體。

我可能會建議的一件事就是不要放入Branch.GetListOfBranches(),而是想出一個像DataLayer.cs之類的類,將盡可能多的查詢邏輯放在那裏。這樣你就不需要知道你的數據上下文的單個對象,並且當你需要進行修改時,只需要更少的地方就可以完成修改。

我們有一個名爲Sales的數據庫,我們的類叫做SalesDb。然後我們使用該類來檢索我們需要的實體。所以我們可以做一個SalesDb.GetLeads(),甚至是一個SalesDb.GetLeads(Filter f)來過濾掉我們不需要的東西。現在SalesDb正在控制上下文,而我的Leads類不需要知道任何關於它的信息。

+0

貴SalesDb類實際上是倉儲類? – Naor 2011-04-16 17:33:58

+0

或多或少,是的。我們編寫了一堆泛型方法,以便我們可以在存儲庫中進行過濾和排序。我們有Filter 其中T可以是我們的任何db模型(我們通過接口定義它) – taylonr 2011-04-16 17:34:52

1

如果您使用的是波蘇斯作爲外部數據合同, 您可能希望你的模型給你不同的實體/班 爲了防止 您的外部合同和應用程序如何工作之間的鬆耦合。

在數據合同, 你可以從上下文檢索匹配實體的檢索,然後 注入從數據合同價值到使用工具實體/實體, 如ValueInjecter。