2011-07-21 158 views
1

使用一個簡單的例子:實體框架在N層

  • 表示層:ASPX和代碼的後面。
  • 業務層:WCF與 相關的邏輯
  • 數據訪問層:WCF與實體框架

當我想填充網格視圖,將有需要調用一個方法形成的商業邏輯,後者依次調用數據訪問層的方法。

方法和相關邏輯如下。

數據訪問層:

public SampleEntity[] LoadSampleEntity() 
{ 
    //retrieve SampleEntity from database. 
} 

業務邏輯層:

public SampleEntity[] GetSampleEntity() 
{ 
    //call the proxy to access Data Access Tier 
    //Call LoadSampleEntity() 
} 

表示層:

protected void btn_OnClick() 
{ 
    //call the proxy to access Business Logic Tier 
    //Call GetSampleEntity() 
    //SampleEntity[] sampleEntity=BusinessLogic.GetSampleEntity(); 
    //gridview.datasouce = sampleEntity 
    //gridview.databind(); 
} 

鑑於這種結構,如果SampleEntity被修改,所有的3層會需要重新編譯。
當新的屬性/列添加到SampleEntity時,有什麼辦法可以減少重新編譯的需要嗎?我曾經參與

的一種方式將是SampleEntity []轉換爲數據表型在業務邏輯層,並通過數據表到表示層。但是,這樣做會刪除Presentation Tier中的EntityFramework的智能感知功能。

回答

1

您可以嘗試存儲庫模式。您首先會有一個與您的實體對象類似的對象的域圖層,該域圖層將位於它自己的項目/ dll中。您可以使用類似AutoMapper的東西,通過業務層將Entity對象的值映射到Domain對象。然後,表示層會/可以共享域對象層,這樣你抽象的每個表的

IRepository<T> 
{ 
    IEnumerable<T> GetAll(); 
    T GetById(int id); 
    void Save(T saveThis); 
    void Delete(T deleteThis); 
} 

你的T型背後的實體數據層將域類型和這些方法裏面你會映射實體類型爲您的域類型。此IRepository可以是您在數據層訪問上的服務合同。

至於你的其他問題,您對實體對象的任何改變都需要反映在域對象不過這可以通過類似AutoMapper來完成。我認爲在大多數情況下,您不希望將EF或LinqToSql數據類型共享到視圖或用戶界面。

既然是WCF,你可以讓域層爲你的序列化類型。

+0

這對我很有用。我其實不想公開這個實體,而是做一些像你一樣的事情。但我不確定是否有辦法做到這一點,而不會影響我的開發時間。現在你來談談automapper。automapper是否像object.getType()?如果你不介意,你可以根據各種層次向我展示僞或代碼嗎?使用你的方法,我可以看到iRepository在業務層面上提供的幫助,但是就表現層而言,我應該如何訪問T? –

+0

Automapper只是一種將狀態從一個對象轉移到另一個對象的方式,就像這樣。你可以在codeplex上查看它,我使用自己的自制反射映射方案,但Automapper會做得更好。基本上你可以用上面顯示的合同將每個表格表示爲它自己的wcf存儲庫服務(儘管你真的不能在WCF中使用通用接口)。 –

+0

然而,您可能會或可能會將在合同/存儲庫中由T表示的您的域對象共享到表示層,就像您上面使用SampleEntity共享它一直到表示層一樣。您的表示層只會瞭解從IRepository服務返回給您的域對象。它將無法知道實現此合約的服務內部(數據環境和轉換到域對象的所有細節)。 –

0

您可能有興趣使用在服務器端使用實體框架的開源N-Tier Entity Framework,並生成用於構建基於WCF的n層體系結構的整個基礎架構,其中包括客戶端上類似EF的API。看看框架的可供下載在CodePlex用戶指南,它包含架構考慮的一整節。