【问题标题】:Server-side Fetchxml returns different results服务器端 Fetchxml 返回不同的结果
【发布时间】:2012-07-07 01:50:16
【问题描述】:

我们的一个程序允许用户通过选择一个视图然后点击功能区按钮来批量插入相关记录。保存表单,设置标志,然后插件完成其工作。

我们使用带有视图选择器的子网格来让用户动态选择或创建自己的视图。选择视图后,将显示结果数(提供 lte 5k)。

当插件运行相同的 fetchxml 服务器端(检索用户查询或保存查询,然后检索 + FetchExpression)时,结果会发生变化。我们不仅得到不同数量的记录,而且有些记录也不同。

我们得出结论,该问题与时区有关。一些过滤器包括“on-or-after”运算符以及日期值。 示例:

<filter type="and">
  <condition attribute="modifiedon" operator="on-or-after" value="2011-01-01" />
  <condition attribute="modifiedon" operator="on-or-before" value="2011-12-31" />
</filter>

插件以管理员身份运行。更改插件用户无效 - 就好像使用 FetchExpression 从 CRM 提取记录时不考虑当前用户时区一样。

如何确保 fetchxml 表达式在客户端和服务器端返回相同的结果?

可能相关:MSDN thread

感谢您的宝贵时间。

编辑:按照 Daryl 的建议,我运行了 SQL 跟踪。结果令人费解。客户端查询的日期正确偏移(从 CRM 运行,即高级查找) - 这意味着使用用户的时区设置正确翻译了 fetchxml。对于服务器端的相同查询,这不会发生;输出 SQL 包含“原样”的日期过滤器,没有时区偏移。我假设无论查询执行上下文的来源如何,都会发生相同的翻译。

编辑 2:隐藏代码区域中的一个标志(我最后的调试手段)阻止插件在运行用户的上下文中实例化服务。现在一切运行良好。感谢大家的时间和帮助,非常感谢。

【问题讨论】:

  • 可能不是,但值得确认它不是安全权限问题。当您以管理员和用户身份查询时,您会看到更多记录吗?您是否为您在此处使用的用户分配了管理员安全角色?
  • 你是说这两个 fetch 语句不完全相同,因为一个包含“on-or-after”和“on-or-before”而另一个使用了其他内容?
  • @BenPatterson1,首先注意到此问题的用户和我自己的用户都具有管理员级别的权限。感谢您的评论。
  • @PaulWay:澄清一下,fetchxml 碰巧包括上面的日期运算符。我从高级视图编辑器下载了 fetchxml,然后在服务器端提取它,最后我通过 IE 调试器从表单中的网格控件中提取它——它们都匹配。结果不会,具体取决于执行 fetchxml 的位置。谢谢。
  • @Raine 好的,并进一步澄清...您从两个位置(或特别是同一用户)运行它,得到不同的结果?

标签: plugins dynamics-crm-2011 fetchxml


【解决方案1】:

处理日期时,请始终记住转换为 utc,因为 CRM 就是这样将它们存储在数据库中的。

本机 CRM 高级查找将查看当前用户的时区,并在执行 SQL 查询之前将他们输入高级查找的任何时间转换为 UTC。您的插件控件将需要做同样的事情。这些是在将条件放入 Fetch Xml/Linq 表达式/查询表达式之前需要执行的步骤。

  1. 通过用户的 SystemUserId 获取用户的 UserSetting.TimeZoneCode。
  2. 在 TimeZoneDefinition.StandardName 中查找步骤 1 中的 TimeZoneCode
  3. 调用 TimeZoneInfo.FindSystemTimeZoneById(),传入步骤 2 中的标准名称(您可以将步骤 1 和 2 合并到一个查询中,但我更喜欢使用步骤 1 中的输入缓存步骤 3 的结果以获得轻微的性能改进。即使用以 TimeZoneCode 作为键,TimeZoneInfo 作为值的字典)
  4. 使用此函数获取您将在插件查询中使用的时间的 UTC 值:

public static DateTime ConvertTimeToUTC(DateTime time, TimeZoneInfo timeZone)
{
    if (time.Kind != DateTimeKind.Unspecified)
    {
        // If the DateTime is created with a specific time zone(ie DateTime.Now), getting the offset will
        // blow chow if it isn't the correct time zone:
        // The UTC Offset of the local dateTime parameter does not match the offset argument.
        //Parameter name: offset

        // This quick check will recreate the serverLocal time as unspecified

        time = new DateTime(
            time.Year,
            time.Month,
            time.Day,
            time.Hour,
            time.Minute,
            time.Second,
            time.Millisecond);

    }
    var offest = new DateTimeOffset(time, timeZone.GetUtcOffset(time));
    return offest.UtcDateTime;
}

【讨论】:

  • 这通常是一个合理的建议,但我不确定我是否理解它在这种特定情况下的帮助。我没有使用特定的日期字段。我正在运行 fetchxml 并在运行服务器端时得到不同的结果。 fetchxml 未修改,并且恰好包含日期运算符。问题可能是本地到UTC的转换,我可能正在寻找防止这种情况的方法。谢谢。
  • @raine 我想我对运行客户端的意思感到困惑。我假设您使用的是javascript?我建议打开跟踪并确保 fetch XML 以与您期望的相同的方式正确地转换为 SQL 查询。这将有助于缩小哪一方存在本地与 UTC 问题...
  • Daryl,当我提到客户端时,我指的是常规 CRM 使用,例如更新子网格或使用标准高级查找功能运行查询。跟踪建议很有趣,我要试一试。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 2013-07-16
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多