2011-12-06 189 views
3

我正在開發一個使用WPF/MVVM的應用程序。我有一個WCF數據服務項目,它提供了使用實體框架從ADO.NET數據模型中檢索數據的操作。然後我有一個wpf客戶端,它綁定到從WCF服務中獲取的viewmodel屬性。該場景涉及客戶/辦公室。客戶端實體具有Office類型的導航屬性,這是作爲數據庫中的外鍵實現的。問題是,當我的viewmodel從數據服務獲取客戶端列表時,導航屬性爲空。服務操作不過檢索這些信息。導航屬性丟失?

WCF服務操作

[OperationContract] 
public IEnumerable<Client> GetClientsByOffice(int officeID) 
{ 
    using (var context = new LDC_Entities()) 
    { 
     var result = context.Clients.Include("Registered_Office") 
      .Where(c => c.Registered_Office_ID == officeID).ToList(); 

     result.ForEach(c => context.Detach(c)); 
     return result; 
    } 
} 

正如你所看到的寫字樓,是上下文查詢中加載。如果我在此處放置斷點,則結果變量將保存客戶端信息,導航屬性也按預期填充。

WPF視圖模型

private void RefreshClients() 
{ 
    serviceClient.GetClientsByOfficeCompleted += (s, e) => 
    { 
      Clients = e.Result; 
      foreach (Client c in Clients) 
       MessageBox.Show(c.Office.City); 
    }; 

    this.serviceClient.GetClientsByOfficeAsync(CurrentOffice.Office_ID); 
} 

如果我檢查客戶端屬性調用此方法後,導航性能現在是空的,這樣的消息框調用我把拋出一個空指針異常。看起來,當它通過WCF服務時,它會刪除客戶端對象的導航屬性。

請任何人都可以解釋這個信息如何保留時,這個電話?

提前許多感謝, 麥克

回答

1

正如你所看到的寫字樓,是上下文查詢中加載。如果我在此處放置斷點,則結果變量將保存客戶端信息,導航屬性也按預期填充。

我不確定你說的是哪一點,因爲那裏有多行代碼。但是the object graph gets shredded when you detach entities

在這個問題提出的解決方案是使用NoTracking查詢,所以你不必分離:

using (var context = new LDC_Entities()) 
{ 
    context.Job.MergeOption = MergeOption.NoTracking; 
    return context.Clients.Include("Registered_Office") 
     .Where(c => c.Registered_Office_ID == officeID) 
     .ToList(); 
} 

該解決方案可能會更好地爲您比它在這個問題沒有,因爲他們還需要做一個更新,這需要對象跟蹤,而你只是在做一個查詢。

解決此問題的另一種方法是避免將類從數據持久層暴露給更高層。那麼你不必擔心諸如實體序列化之類的事情,因爲直接使用數據持久層時只能與它們一起工作。這也帶來了其他優點,例如層之間的鬆散耦合,以及將更少不必要的數據暴露給更高層。使用像AutoMapper這樣的庫可以幫助減少圖層之間複製數據的一些樣板。

+0

太棒了,這完全回答了我的問題,它現在按預期工作。感謝您的明確解釋和道歉,我不知道「對象圖」是什麼,所以找不到其他解決方案。感謝替代技術和重新定義的架構的建議,將考慮未來。再次感謝 –

+0

@MikeScott:NP,這就是我們在這裏的原因:)我認爲「導航屬性」在談論EF時更常用,並且對於有同樣問題的人來說更容易搜索。至於重做你的架構,我建議你做一些最便宜和最簡單的事情,直到你經常碰壁,或者你的架構開始看起來w。不前。 –