2012-04-25 47 views
2

我有以下方式的客戶端服務器應用程序。我可以選擇檢索protobuf-net或NHibernate中的對象字段嗎?

enter image description here

在域有的班級有孩子的集合。有些孩子參考他們的父母。

與問題是,當一個請求到服務器的一個子對象進行,所有其他的孩子都在響應返回。在許多情況下,從子項訪問父對象是非常有幫助的,我不希望爲父項創建一個單獨的請求,因爲這會導致更多的往返行程。

通常Nhibernates延遲加載會照顧這可是與交互protobuf網(或任何其他序列化)是指所有的字段訪問被序列化。客戶端不能直接訪問數據庫。

是否有可能以protobuf-net或Nhibernate的方式限制對象的引用深度,這樣我可以在服務器的請求中包含一個標誌,指出不加載超過2個對象的標誌。

例如 訂單 - 訂單商品 - 送貨信息。

之一上的順序的請求的限制意味着不加載傳遞信息。限制爲0意味着不加載訂單項目。

Altenatively是它可以任意地被加載停止的引用(極限是0或無限制),這是更嚴格的,但可能更可行的實現。

回答

2

protobuf網支持ShouldSerialize *圖案(在共同與幾個BCL實施方式中,包括IDE/PropertyGrid中,和XmlSerializer的)。

如果您有:

[ProtoMember(1)] 
public int Whatever { get; set; } 

而且相應:

public bool ShouldSerializeWhatever() { 
    ... 
} 

那麼無論是如果ShouldSerializeWhatever返回true唯一序列化。這種模式完全是基於名稱的。該方法可以是公開的或非公開的(但是XmlSerializer只接受公共方法,因此如果使用多個序列化程序,請保持公開)。

+0

謝謝Marc,我用IMO定義我的合約是一種奇怪的方式,可以直接調用AddType,AddField和AddSubType。我在AddField的返回值上找到了一個'SetSpecified'方法,當給定一個方法的時候,它是一樣的嗎? – 2012-04-26 10:03:32

+0

@詹姆斯 - 是的,這是一回事;命名是由於也支持'* Specified' BCL模式,以及這種模式允許雙向使用(而不是'ShouldSerialize *',這是單向的)的事實。不過,同樣的事情。 – 2012-04-26 11:06:56

0

嗯,首先,這並不真的有什麼關係protobuf網,因爲它僅僅是serialier,只是連載你給它,所以你只需要深給它2級。

這實際上都是在你的邏輯中完成的。我假設你正在做的是序列化來自nhibernate的實際對象。您可能想要做的是introduce DTO's,它將用作服務的響應,並將數據從您的對象複製到DTO,從而使您只能深入兩層。

將數據複製到DTO's可能很乏味,並且有像AutoMapper這樣的項目旨在讓您的生活在這方面更簡單,但我不確定對映射有多少控制,您只能指定哪裏去2級深度,因此可能需要手動映射。

+0

我想知道如果protobuf網有一個選項「不要串行化這個成員」。這將允許Nhibernate的延遲加載再次生效。你是對的,我只是直接序列化域對象。 – 2012-04-25 15:40:10

+0

我會爲DTO路由爭辯,因爲雖然你可以添加屬性來忽略成員,但是當你發送給客戶端時,你可能會跑到別的地方想要序列化那個成員,所以你就回到原點了,因爲你是序列化核心對象而不是映射。 – 2012-04-25 15:43:21

+0

下面是我在談論的一個例子:http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ – 2012-04-25 15:46:40