2011-03-21 66 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

相关问题