我正在使用WPF / MVVM开发应用程序。我有一个WCF数据服务项目,它提供了使用实体框架从ADO.NET数据模型中检索数据的操作。然后我有一个wpf客户端绑定到从WCF服务获取的viewmodel属性。该方案涉及客户/办公室。客户端实体具有office类型的导航属性,实现为数据库中的外键。问题是当我的viewmodel从数据服务获取客户端列表时,navigation属性为null。但是,服务操作会检索此信息。
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;
}
}
如您所见,office属性是在上下文查询中加载的。如果我在此处设置了断点,则结果变量保存客户端信息,并且导航属性也按预期填充。
WPF ViewModel
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);
}
如果在调用此方法后检查Clients属性,则导航属性现在为空,因此我输入的消息框调用会抛出空指针异常。看来,当它通过WCF服务时,它会删除客户端对象的导航属性。
请允许任何人解释在拨打此电话时如何保留此信息?
非常感谢, 麦克
答案 0 :(得分:1)
如您所见,office属性是在上下文查询中加载的。如果我在此处设置了断点,则结果变量保存客户端信息,并且导航属性也按预期填充。
我不确定你在谈论哪一点,因为那里有多行代码。但是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这样的库可以帮助减少在层之间复制数据的一些模板。