2011-03-21 62 views
1

我正在使用Model類上的DataAnnotation屬性進行驗證,並且Model類用於在應用程序的Client和Server端進行驗證。如何在不引起循環引用的情況下使用LazyLoading和WCF?

我的問題是,如何延遲加載我的模型的屬性,而不會導致循環引用

所涉及的庫我想不出有:

  • WCF服務庫
  • 客戶端數據訪問圖書館
  • 模型庫

,因爲這些模型天秤座ry在客戶端和服務器端用於數據驗證,我無法從模型庫中引用DataAccess庫。因此,我如何設置延遲加載?

例如,我有一個ConsumerModel,它具有PhoneNumbers屬性,應該延遲加載。如何在不引用客戶端DAL的情況下從ConsumerModel中加載PhoneNumberModels?

客戶端DAL:

using MyModels; 

public class ConsumerDataAccess 
{ 
    public ConsumerModel GetConsumerById(int id) 
    { 
     ConsumerDTO dto = WCFService.GetConsumer(id); 
     return new ConsumerModel(dto); 
    } 
} 

ConsumerModel:

public class ConsumerModel 
{ 
    public ObservableCollection<PhoneNumberModel> _phoneNumbers; 

    public ObservableCollection<PhoneNumberModel> PhoneNumbers 
    { 
     get 
     { 
      if (_phoneNumbers == null) 
      { 
       // Can't reference DataAccess Library since that would cause a Circular Reference 
      } 
     } 
    } 
} 

什麼是一些替代辦法,我可以使這個架構的工作?

我傾向於使用模型進行驗證,並使用客戶端和服務器端的模型進行驗證。我還希望繼續使用DataAnnotation進行驗證。

編輯

這是我根據勞倫斯·溫漢姆的答案最終解決方案,如果有人有興趣。我結束了使用委託而不是事件。

DAL:

public class ConsumerDataAccess 
{ 
    public ConsumerModel GetConsumerById(int id) 
    { 
     ConsumerDTO dto = WCFService.GetConsumer(id); 
     ConsumerModel rtnValue = new ConsumerModel(dto); 
     ConsumerModel.LazyLoadData = LazyLoadConsumerData; 
     return rtnValue; 
    } 
} 

private object LazyLoadConsumerData(string key, object args) 
{ 
    switch (key) 
    { 
     case "Phones": 
      return PhoneDataAccess.GetByConsumerId((int)args); 
     default: 
      return null; 
    } 
} 

模型庫:

public class ConsumerModel 
{ 
    public delegate object LazyLoadDataDelegate(string id, object args); 
    public LazyLoadDataDelegate LazyLoadData { get; set; } 

    public ObservableCollection<PhoneNumberModel> _phoneNumbers; 

    public ObservableCollection<PhoneNumberModel> PhoneNumbers 
    { 
     get 
     { 
      if (_phoneNumbers == null && LazyLoadData != null) 
      { 
       _phoneNumbers = (ObservableCollection<PhoneNumberModel>) 
         LazyLoadData("Phones", ConsumerId); 
      } 
      return _phoneNumbers; 
     } 
    } 
} 

回答

2

一種方式是提高模型中的類屬性的get {}一個事件,然後實現在一個延遲加載經理客戶端有一個參考您的DAL。 EG:

public class LazyLoadEventArgs: EventArgs 
{ 
    public object Data { get; set; } 

    public string PropertyName { get; set; } 

    public int Key { get; set; } 
} 

然後在您的模型類:

public event EventHandler<LazyLoadEventArgs> LazyLoadData; 

public ObservableCollection<PhoneNumberModel> PhoneNumbers 
{ 
    get 
    { 
     if (_phoneNumbers == null) 
     { 
      LazyLoadEventArgs args = new LazyLoadEventArgs { 
       PropertyName = "PhoneNumbers", 
       Key = this.Id 
      }; 
      LazyLoadData(this, args); 
      if (args.Data != null) 
       this._phoneNumbers = args.Data as ObservableCollection<PhoneNumberModel>; 
     } 
     return _phoneNumbers; 
    } 
} 

爲LazyLoadData事件將有來自客戶端的DAL獲取數據,然後將其存儲在的.Data財產的工作處理程序LazyLoadEventArgs。 EG:

private void Model_HandleLazyLoadData(object sender, LazyLoadEventArgs e) 
{ 
    switch (e.PropertyName) 
    { 
     case "PhoneNumbers": 
      e.Data = DAL.LoadPhoneNumbers(e.Key); 
      break; 
     ... 
    } 
} 
+0

我不知道我明白......實際上調用DAL加載PhoneNumber數據的是什麼? – Rachel 2011-03-21 20:08:45

+0

查看編輯答案。 LazyLoadData的事件處理程序是調用DAL的事件處理程序。您需要找出識別要加載的數據的最佳方式;在我的例子中,我只是使用了某種字符串和'Key',但是可以使用枚舉,將其與'if(sender is ConsumerModel)'等組合在一起。它會使DAL不在模型中。 – 2011-03-21 20:23:33

+0

這不會給我一個循環引用問題嗎?模型需要了解觀察者庫,觀察者需要了解模型庫。我最初的問題是我無法從模型庫中引用DAL,因此我無法將這兩者結合起來。 – Rachel 2011-03-22 12:40:05

0

不要對WCF使用「延遲加載」。網絡通信耗費時間。如果您打算使用PhoneNumbers,則您的服務應該公開將使用電話號碼返回Customer的方法。其他方法是使用WCF Data Services,它提供了客戶端linq查詢,能夠通過Expand方法定義急切加載。

您應該將服務呼叫降至最低。

再次閱讀您的問題後,我不明白爲什麼你分享模型之間的服務和客戶端。模型是嚴格的客戶端功能。唯一的共享部分應該是DTO。

+0

PhoneNumbers是一個簡單的例子。一個更好的例子可能是文檔,因爲在大多數情況下,文檔是大文件,我不想在任何情況下檢索它們。用戶可以自定義他們的用戶界面,因此在屏幕上具有文檔部分的用戶需要加載文檔,而其他用戶則不需要。 – Rachel 2011-03-21 20:11:08

+0

聽起來像不同的觀點,有不同的模型和不同的方法來檢索數據。 – 2011-03-21 20:12:47

+0

每個數據段都有不同的視圖。用戶可以將面板拖放到屏幕上,具體取決於他們需要使用哪些信息。在幾乎所有情況下,小組都包含有關消費者的信息。當他們加載消費者時,我只需要根據屏幕上顯示的面板加載屏幕上的信息。 – Rachel 2011-03-21 20:15:17

相關問題