2012-08-10 184 views
4

我有一個域模型的服務,我想向客戶展示數據。服務具有典型的體系結構:數據庫,ORM(EF),具有域模型的業務層。WCF DataServices&映射DTO

我想使用WCF DataServices向客戶端公開數據,但我無法將數據對象從域模型發送到客戶端。我將使用DTO與客戶進行交互,並且我有數據對象映射。

DataServices有反射提供程序,在這種情況下似乎很好(讓我們考慮只讀場景)。但反思提供者要求IQueryable<dto>屬性被暴露。這就是問題所在。所以我看到以下方法來解決它:

  1. 加載所有域對象,將它們映射到dtos並返回結果dtos。真的很糟糕的方法,如果有很多域對象存在。
  2. 創建一個「linq2dto」提供程序並生成動態通訊錄「linq2EF」查詢,在查詢實體化處從數據庫獲取數據對象並執行映射。它聽起來不錯,但正如我所看到的,這是一項複雜的任務。

所以,夥計們,我需要幫助。我不想寫(並支持!)新的LINQ提供程序。可以在哪裏有一些「通用linq2anyware」實現,我可以使用?

另一方面,我真的不能將數據對象暴露給客戶端並使用DataServices EF提供程序。是否有一些簡單的方法來實現這種映射?

+0

首先問明顯的問題:你真的需要DTO嗎?先用EF代碼不足以滿足您的需求? – 2012-08-10 16:23:37

回答

1

不幸的是,如果你真的開始使用DTO,你需要將查詢樹翻譯的工作轉移到EF可以使用的東西上。這很可能會讓你進入自定義提供商領域,這是你必須處理的另一個問題。

對於特定的查詢樹翻譯,您可能會看到類似re-linqIQ toolkit的內容。

我們可以在關於您爲什麼需要DTO的問題的評論中進行簡短對話嗎?如果他們能夠理解這些細節,我認爲這個問題對其他人更有用。

+1

由於以下原因,我使用DTO: 1.獨特的服務器和客戶端代碼。它將簡化代碼重構,所以我可以更改服務器數據對象,更正映射並更改客戶端對象 2.從客戶端隱藏服務器端代碼(將數據對象映射到數據庫表) 3.添加一個擴展點以使攔截客戶端調用並以特定方式處理它們的機會 – Sergey 2012-08-13 07:56:13

+0

我不確定這是否完全回答您的觀點,但我會回覆如下:1.客戶端代碼實際上與服務器代碼有所不同 - 您可以將自己的POCO到WCF數據服務,或者如果您使用添加服務引用,我們將爲您生成代理類。如果您在客戶端使用您自己的POCO,重構服務器和客戶端可能會更容易。 2. EF Code First在照顧對象 - RDBMS「阻抗不匹配」方面已經做得相當不錯。如果你還沒有,你應該玩這個。 3.你看過QueryInterceptors/ChangeInterceptors嗎? – 2012-08-13 17:30:07

+0

@Sergey:你選擇了哪條路線,關於你提供的3個理由?我現在處於同樣的狀況。您是否按照Mark的建議使用客戶端和服務器端的POCO?如果是這樣,你有沒有遇到任何安全問題? – 2014-01-27 14:03:19

1

總之,手動編寫每個DTO。

可能不是您正在尋找的答案,但這是我的建議。如果你不能暴露的實際類型,手動編寫一個輕量級的衛星類型,例如

class Foo 
{ 
    //large domain type 

    FooDTO ToDTO() 
    { 
     return new FooDTO(...) 
    } 
} 

class FooDTO 
{ 
    //lightweigh 
} 

我還沒有看到任何LINQ提供程序,可以幫助你做出一個通用的轉換器,但也許這是因爲我有限的經驗。反對使用泛型轉換器的另一個觀點是,域類型可能需要非常具體的指示,指出要包含在輕量級對象中的內容以及要排除的內容。

或者,您可能會嘗試編寫一個使用反射的通用類來檢查所有公共屬性並返回一個serrialised對象,但是如何知道線的另一端的對象的類型(if你不能使用你的域名類型)?