导航属性丢失?

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);
}

如果我在调用此方法后检查Clients属性,则导航属性现在为空,因此我放置的消息框调用会抛出空指针异常。看起来,当它通过WCF服务传递时,它会删除客户端对象的导航属性。
请问如何在进行此调用时保留此信息?
非常感谢您的帮助, Mike
1个回答

1
正如您所看到的,办公室属性是在上下文查询中加载的。如果我在这个点上设置断点,结果变量保存了客户信息,并且导航属性也按预期填充。
我不确定您指的是哪个点,因为那里有多行代码。但是当您分离实体时,对象图会被破坏
该问题提出的解决方案是使用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这样的库可以帮助减少在层之间复制数据的样板文件。


太棒了,这完全回答了我的问题,并且现在按照预期工作。感谢您清晰的解释,对于我不知道“对象图”是什么,因此找不到其他解决方案表示歉意。感谢您推荐替代技术和重新定义的架构,将来会考虑。再次感谢。 - Mike Scott
@MikeScott:没问题,这就是我们在这里的原因 :) 我认为在谈论EF时,“导航属性”更常用,并且对于遇到相同问题的人来说更易搜索。至于重新设计架构,我建议先做最便宜和最容易的事情,直到你经常遇到瓶颈或者你的架构开始变得复杂难懂。 - Merlyn Morgan-Graham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接