2009-04-19 115 views
2

我使用.net 2.0與NHibernate/ActiveRecord和WCF。wcf序列化和nhibernate延遲加載

到目前爲止,我還沒有使用NH懶惰負載,但性能處罰太大而無法忽略,所以我開始使用它。

從我目前閱讀的內容來看,這不是一個簡單的主題,使用NH實體進行延遲加載和序列化到WCF,但好處太大,無法忽略。

使用代碼我在這裏找到:WCF Serialization With NHibernate,我已經能夠讓WCF識別基本類型。

我也創建DataContractSerializer的是這樣的:

public override XmlObjectSerializer CreateSerializer(Type standard, XmlDictionaryString name, XmlDictionaryString NS, IList<Type> knownTypes) 
{ 
    return new DataContractSerializer(standard, name, NS, knownTypes, 0x989680, false, true /* Preserve References*/, new HibernateDataContractSurrogate()); 
} 

我的問題是,當我有這樣的事情:

[DataContract, ActiveRecord("POS_POSCUSTOMERS",Lazy = true)] 
public class POSCustomer : ActiveRecordForPOS<POSCustomer> 
{ 
    private Branch belongsToBranch; 

    [DataMember,BelongsTo("BRANCH")] 
    public virtual Branch BelongsToBranch 
    { 
     get { return belongsToBranch; } 
     set { belongsToBranch = value; } 
    } 
} 

[DataContract, ActiveRecord("BRANCHES",Lazy = true)] 
public class Branch : ActiveRecordForPOS<Branch> 
{ 
    private POSCustomer defaultPOSCustomer; 

    [DataMember, BelongsTo("POS_POSCUSTNUM", Cascade= CascadeEnum.None)] 
    public virtual POSCustomer DefaultPOSCustomer 
    { 
     get { return defaultPOSCustomer; } 
     set { defaultPOSCustomer = value; } 
    } 
} 

Branch.DefaultPOSCustomer和POSCustomer.BelongsToBranch是兩個不相關的實體,但它們是相同的實體例如科200 DefaultPOSCustomer 100,和POSCustomer具有BelongsToBranch 200

的問題是,當WCF嘗試序列化對象圖,它DefaultPOSCustomer和BelongsToBranch之間跳動,彷彿不承認它們是相同的實體並且已經將它們序列化,直到它發生堆棧溢出。

如果我關閉這些類的Lazy = true,序列化就可以正常工作。

  1. DataContractSerializer如何確定實體已被序列化?
  2. 如何阻止此行爲?
  3. 是否有其他方式序列化延遲加載實體與WCF?

p.s.我一直在考慮另一種解決方案,即創建類似於NHibernate Proxy的解決方案,但用原始密鑰替換與其他類相關的屬性,所以不是具有Branch類型的屬性,而是具有int類型的屬性值爲200.這樣我可能能夠避免我遇到的循環問題,但我會嘗試這是最後的手段,因爲這將是非常複雜的維護。

編輯:我有很多實體,因此爲每個實體創建一個dto是不可能的,而且動態創建它會很複雜,所以我寧願避免這種情況,或者將它作爲最後的手段使用。我還需要在服務器端做業務邏輯,所以我需要的是實體而不是原始數據。

編輯:好吧,沒有運氣直接NH/AR/WCF的方式。我會去創建看起來更簡單的DTO。

+1

爲什麼不創建一個DTO用於您的web服務? – Paco 2009-04-19 18:22:17

回答

2

我只注意到我沒有關閉我的問題,我使用了DTO解決方案,它的工作效果很好。

0

回答已經太遲了;-)但無論如何,這是因爲延遲加載的對象是NH代理類;看起來像這樣加載時它們是不同的。 一種解決方案是覆蓋.Equals()以比較持久實體的Id屬性。我猜你的實體有類似主鍵的東西。這可能會使WCF開心,只要它使用平等,而不是引用比較。如果WCF總是使用ReferenceEquals - 沒有運氣。

0

我們一直在使用this解決方案,並發現它比DTO解決方案更容易/更好。