【问题标题】:How to make WCF Dataservice to stop tracking Entity changes?如何使 WCF Dataservice 停止跟踪实体更改?
【发布时间】:2012-10-28 11:52:09
【问题描述】:

我有一个通过代理调用 OData Webservice (DataServiceContext) 的 Web 应用程序。问题是代码即使每次都调用 OData webservice,但它总是在内容管理系统 (SDL Tridion) 中更改内容后返回旧数据。

string getPageContentForUrl(string url)
{
    var page = cdService
                   .Pages
                   .Expand("PageContent")
                   .Where(x => x.Url == url)
                   .FirstOrDefault();

    if (page == null || page.PageContent == null)
    {
        return string.Empty;
    }
    else
    {
        return page.PageContent.Content;
    }

}

我们必须重置应用池才能看到最新的数据更改。

所以在进行更多调试时,我注意到

var context = (System.Data.Services.Client.DataServiceContext)cdService;
context.Entities[0].State = Unchanged

所以我尝试通过显式调用.Detach() 来修复它,然后从getPageContentForUrl 返回值,就像这样,

cdService.Detach(page);
cdService.Detach(page.PageContent);

我的问题是,我是否可以在更“全局”的级别上执行上述操作,也许让 web 服务始终假定状态为“已更改”,因为我不想手动将代码写入 Detach()

【问题讨论】:

  • 我认为没有必要分离。内容交付服务可以设置为缓存来自代理的内容。请打开CDS中的cd_storage_conf.xml,关闭缓存重试。
  • 谢谢 Quirijn,你能看看我对 Frank 回答的评论吗
  • 我认为你是对的,请在下面查看我的回答,看看是否有帮助。

标签: wcf-data-services odata tridion tridion-content-delivery


【解决方案1】:

我认为答案确实在于 - 正如您所怀疑的 - 在您正在使用的代理中,或者更确切地说在 DataServiceContext 中。这就是微软不得不说的:

默认情况下,客户端仅在响应提要中具体化一个条目 为尚未被 数据服务上下文。这意味着对已经在 缓存不会被覆盖。这种行为是通过指定一个 查询和加载操作的 MergeOption 值。

对我来说,这听起来与您所描述的行为完全一样。幸运的是,可以通过在 DataServiceContext 上设置 MergeOption 属性来关闭缓存。

http://msdn.microsoft.com/en-us/library/gg602811.aspx

【讨论】:

  • 是的,解决了这个问题,我必须设置 MergeOption = NoTracking,因为 OData WS 是现成的。
  • 谢谢! Microsoft.OData.Client.DataServiceContext.MergeOption 有同样的问题,因为它默认为“AppendOnly”。设置为 context.MergeOption = MergeOption.PreserveChanges 为我解决了这个问题。 docs.microsoft.com/en-us/dotnet/api/…
【解决方案2】:

正如 Quirijn 已经评论的那样,Tridion Content Delivery OData 服务似乎在您的设置中返回缓存的结果。分离和重新连接客户端是一种蛮力解决方法。

Tridion Content Delivery 对象缓存将(如果配置正确)在内容管理系统中的发布操作更新项目时自动从其缓存中删除项目。由于您的设置中没有发生这种情况,因此您的对象缓存似乎没有正确配置。

最简单的步骤是找到 cd_webservice Web 应用程序的 cd_storage_conf.xml 文件并关闭对象缓存(正如 Quirijn 已经说过的):

<ObjectCache Enable="false" />

现在像以前一样回收应用程序池并再次测试。如果现在 OData 调用总是返回更新的内容,那么您的问题确实是由错误配置的对象缓存引起的。

不幸的是,在这个阶段,您所要做的就是关闭对象缓存,这肯定会减少您的 Web 服务可以处理的负载。下一步应该是修复对象缓存的配置问题。

为此,我建议您联系 SDL 专业服务部门或 SDL 的合作伙伴之一。虽然配置Object Cache并不太难,但是用问答的形式解释起来有点牵强。

【讨论】:

  • 感谢您的回答。我想我的问题并不清楚,当我在浏览器中触发实际的 Odata 调用时,我得到了更新的内容,mydomain/odata.svc/… 我们已经实现了一个 CacheChannel 服务,它在新数据发布时清除 OData WS 缓存。问题在于代码 (getPageContentForUrl) 中,该代码使用显示旧数据的代理 (DataServiceContext) 调用 OData WS。这是否意味着 OData WS 设置正常但代理设置不正常?
  • 啊...如果浏览器显示更新的内容,问题确实在客户端。我从未见过生成的代理返回过时的内容,所以很遗憾对此无能为力。
  • Quirijn 的建议解决了这个问题。必须设置 MergeOption - 请参阅我对他的回答的评论。
猜你喜欢
  • 1970-01-01
  • 2017-11-27
  • 2011-04-23
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多