2011-06-15 23 views
4

我在繞虛擬代理服務器時遇到了一些麻煩。我已經閱讀了大量的文章,並花了幾個小時試圖找到好的信息,但我還沒有找到全面的東西。所以我會在這裏提出一個通用的請求以獲得更好的信息(或者發佈在這裏或者只是一個鏈接)。我還將在下面添加一些細節以更好地解釋我到底想要什麼。虛擬代理如何工作?

我有幾個對象,它們之間有很多引用。爲了簡潔起見,我將有一個具有基本父 - 子關係的對象(節點)。當我把這個對象拉出數據庫時,我想實現延遲加載。從我讀過的內容來看,虛擬代理將通過引用接口(INode)和根據需要提取數據成員來基本上處理所有延遲加載。 [注意:我實際上沒有一個INode類,但是當我將虛擬關鍵字放在我的數據成員上時,似乎使用了代理]

當我在虛擬類中創建數據成員時,一個代理。這是一個虛擬代理嗎?這些是否實現了延遲加載?

我搜索了關於virtual關鍵字的信息,但是我能找到的唯一文檔就是在方法上使用它,它用於繼承,以便派生類可以覆蓋函數,這與我想要的無關(我認爲)。

這是我目前Node.cs

[DataContract(IsReference=true)] 
public partial class Node 
{ 
    [DataMember] 
    public long ID { get; private set; } 
    [DataMember] 
    public virtual Node Parent { get; set; } 
    [DataMember] 
    public virtual ICollection<Node> Children { get; set; } 
} 

基本上在這一點上,我很迷茫,只需要對這個話題的一些指導,甚至是一種在線資源,我可以看看,因爲所有的人我發現一直沒有什麼幫助。

在此先感謝。

回答

5

「虛擬」 代理和延遲加載的東西有關ORM工具。代理實際上不是虛擬的,它是動態的,它遵循由GoF定義的真實代理模式。

動態代理是由ORM工具在運行時創建的類(它並未在任何地方定義爲代碼文件)。它來自你的實體,它覆蓋了導航屬性。因爲它們必須是虛擬的才能進行代理工作。該代理在私有字段或任何更復雜的結構中保存導航屬性的狀態,並且如果第一次訪問該屬性,則會看到該狀態已卸載並觸發從數據庫加載並將狀態更改爲已加載。

無論如何,我不知道這是如何引用WCF,因爲最佳做法是不使用延遲加載WCF。爲什麼?

  • 如果您使用服務器端序列化延遲加載總是會從數據庫整個對象圖拉,因爲序列化可以訪問所有的導航屬性並觸發延遲加載,但隨後將開始序列化延遲加載實體和訪問他們所有的導航性能,等等
  • 在客戶端的延遲加載是模糊的。首先,客戶端的延遲加載完全取決於你 - 你必須實現它。在使用服務時,您應始終遵循以下SOA原則之一:服務邊界是明確的。這意味着您的對象的用戶應該始終知道他正在進行遠程呼叫而不是本地呼叫。分佈式計算的主要目標是減少網絡往返,所以如果可能的話,您應該使用急切加載並在單個往返傳輸所有需要的數據,而不是使用延遲加載。這同樣適用於從數據庫加載 - 在有意義時使用延遲加載,因爲對數據庫進行循環可能會導致代價高昂的操作。
+0

1.如果我要使用動態代理,我該如何序列化/反序列化?我看到了關於DataContractResolver的文章的鏈接,但我從來沒有得到它的工作。 2.我試圖通過DbContext.Configuration進行延遲加載,但我的對象引用仍然爲空。 WCF RIA是不是讓我不是懶加載? – OpticalDelusion 2011-06-15 21:30:42

+0

如果您使用的是WCF RIA Services,您應該在您的問題和標籤中提及它,因爲它是非常具體的技術。 – 2011-06-15 21:45:52

+0

對不起,不打算輸入RIA:P。我在選項卡上跳來跳去,忘記了我正在輸入的內容。只是想說WCF。我能得到它不是懶惰加載的唯一方法是A.使用顯式的.Include,因爲我的模型或B中存在許多關係,這是令人討厭的。使用動態代理,然後失敗,因爲我無法序列化動態代理以供使用在我的服務。我在這一切都很新,基本上已經碰壁了。 – OpticalDelusion 2011-06-15 21:52:52

1

我想你想要一些私人領域支持你的虛擬合適。在獲取這些虛擬屬性的覆蓋時,你檢查私有字段以查看它的當前是否有效(它是否已經從數據庫獲得,是否達到日期等) - 如果沒有,則獲取或重新獲取它。我不認爲它必須比這更復雜。

基類:

private Node _Parent; 
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch. 
} 

覆蓋:

public override Node Parent { 
    get { 
     if (_Parent==null) // or out of date, dirty etc 
      Do_db_get_of_parent(); 
     return _Parent; 
    } 
} 
+0

我不明白這是如何解決我的問題,我猜。你能寫一個快速的代碼片段嗎? – OpticalDelusion 2011-06-15 20:10:24