gpt4 book ai didi

c# - 通过WCF服务的独立自跟踪实体的异步延迟加载导航属性?

转载 作者:IT王子 更新时间:2023-10-29 04:31:37 26 4
gpt4 key购买 nike

我有一个WCF客户端,它将自跟踪实体传递给使用MVVM构建的WPF应用程序。应用程序本身具有动态接口(interface)。用户可以根据自己所扮演的角色或正在执行的任务来选择希望在工作区域中看到的对象。

我的自跟踪实体具有很多导航属性,并且不需要很多。由于其中一些对象可能很大,因此我只想按要求加载这些属性。

我的应用程序如下所示:
[WCF] <---> [ClientSide Repository] <---> [ViewModel] <---> [View]
我的模型是自我跟踪实体。客户端存储库在将模型返回给请求它的ViewModel之前,先连接了LazyLoad方法(如果需要)。所有WCF服务调用都是异步的,这意味着LazyLoad方法也是异步的。

LazyLoad的实际实现给我带来了一些麻烦。这是我提出的选项。

编辑-我删除了代码示例,以尝试使其更易于阅读和理解。如果要查看它,请查看问题的先前版本

选项A

从Getter的WCF服务器异步延迟加载模型的属性

好:按需加载数据非常简单。 XAML中的绑定(bind)将加载数据,因此,如果控件在屏幕上,则数据将异步加载,并在存在该位置时通知UI。如果没有,则没有任何负载。例如,<ItemsControl ItemsSource="{Binding CurrentConsumer.ConsumerDocuments}" />将加​​载数据,但是如果界面的Documents部分不存在,则不会加载任何内容。

错误:在初始化之前不能在任何其他代码中使用此属性,因为它将返回一个空列表。例如,如果尚未加载文档,则以下调用将始终返回false。

public bool HasDocuments 
{
get { return ConsumerDocuments.Count > 0; }
}

选项B

需要时手动调用以加载数据

好:易于实现-只需添加 LoadConsumerDocumentsSync()LoadConsumerDocumentsAsync()方法

错误:必须记住在尝试访问数据之前加载数据,包括在绑定(bind)中使用数据时。这看似简单,但很快就会失控。例如,每个ConsumerDocument都有一个UserCreated和UserLastModified。有一个DataTemplate定义了带有工具提示的UserModel,其中显示了其他用户数据,例如扩展名,电子邮件,团队,角色等。因此,在显示文档的ViewModel中,我必须调用 LoadDocuments,然后遍历它们并调用 LoadConsumerModifiedLoadConsumerCreated 。它也可以继续前进...之后,我必须输入 LoadUserGroupsLoadUserSupervisor。它还具有循环循环的风险,其中像 User这样的东西具有 Groups[]属性,而 Group这样的东西具有 Users[]属性。

选项C

到目前为止,我最喜欢的选项...创建两种访问属性的方式。一同步和一异步。绑定(bind)将完成到Async属性,并且任何代码都将使用Sync属性。

好:数据根据需要异步加载-正是我想要的。也没有太多额外的编码,因为我要做的就是修改T4模板以生成这些额外的属性/方法。

错误:有两种访问同一数据的方式似乎效率低下并且令人困惑。您需要记住何时应该使用 Consumer.ConsumerDocumentsAsync而不是 Consumer.ConsumerDocumentsSync。 WCF服务调用也有可能多次运行,这需要为每个导航属性(例如IsConsumerDocumentsLoaded)额外分配一个IsLoaded属性。

选项D

跳过异步加载,然后将所有内容同步加载到setter中。

好:非常简单,不需要额外的工作

错误:会在加载数据时锁定UI。不要这个

选项E

有人告诉我,还有另一种方法可以做到这一点,并指出代码示例:)

其他说明

在将对象返回给客户端之前,某些NavigationProperty会在WCF服务器上加载,但是另一些则太昂贵了。

除了在选项C中手动调用Load事件之外,所有这些都可以通过T4模板完成,因此我几乎不需要编写任何代码。我要做的就是在客户端存储库中挂接LazyLoad事件,并将其指向正确的服务调用。

最佳答案

仔细考虑一下,首先我必须说,您必须为该问题提供一个清晰的解决方案,当您绑定(bind)到User.Documents属性时,可以异步加载DependecyProperties,但是它的副作用非常严重解决方案。如果我们说View中的这种行为是可以的,那么我们必须非常清楚地了解其余代码的意图,这样我们就可以看到我们如何尝试访问数据-通过某种冗长的命名方式(方法,类名,方法)进行异步或同步别的)。

因此,我认为我们可以使用接近于旧.AsSynchronized()方法的解决方案,创建一个装饰器类,并为每个属性提供私有(private)/ protected AsyncLoad和SyncLoad方法,并且一个装饰器类将是每个lazyloadable的Sync或Async版本上课,更合适。

当您使用Sync装饰器装饰您的类时,它也使用Sync装饰器将每个lazyloadable类包裹在内,因此您将能够使用SynchUser(User).Documents.Counting同步类版本而没有问题,因为它会像
SynchUser(user).SyncDocuments(Documents。)。在Documents属性的重载版本中落后于此,并将调用sync getter函数。

由于同步版本和异步版本都将在同一对象上运行,因此,如果要修改任何属性,此方法将不会导致修改某些未引用的其他对象。

您的任务听起来像可以通过某种神奇的“美丽而简单”的方式解决,但我认为它不可能,或者说它不会比这简单得多。

如果仍然无法解决问题,那么还是100%确保您需要一种清晰的方法来区分代码,无论使用的是同步版本还是异步版本的类,否则您将很难维护代码库。

关于c# - 通过WCF服务的独立自跟踪实体的异步延迟加载导航属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5875271/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com