2

私たちの手順の 1 つは、ユーザーがビューを選択してからリボン ボタンを押すことで、関連するレコードを一括挿入できるようにします。フォームが保存され、フラグが設定され、プラグインが機能します。

ビュー セレクターを備えたサブグリッドを使用して、ユーザーがその場で独自のビューを選択または作成できるようにします。ビューが選択されると、結果の数 (提供されるのは lte 5k) が表示されます。

プラグインがまったく同じ fetchxml サーバー側 (userquery または savedquery の取得、次に取得 + 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 スレッド

御時間ありがとうございます。

編集: Daryl の提案に従って、SQL トレースを実行しました。結果は不可解です。日付は、クライアント側のクエリ (CRM から実行される、つまり高度な検索) に対して正しくオフセットされます。これは、ユーザーのタイムゾーン設定を使用して fetchxml が正しく変換されることを意味します。これは、サーバー側の同じクエリでは発生しません。出力 SQL には、タイムゾーン オフセットのない「現状のまま」の日付フィルターが含まれます。クエリ実行コンテキストの起源に関係なく、同じ変換が発生したと想定しました。

編集 2:コードの非表示領域 (最後のデバッグ手段) のフラグにより​​、実行中のユーザーのコンテキストでプラグインがサービスをインスタンス化できませんでした。現在、すべてが正常に動作しています。お時間を割いてご協力いただき、誠にありがとうございました。

4

1 に答える 1

6

日付を操作するときは、常に utc に変換することを忘れないでください。これは、CRM が日付をデータベースに保存する方法だからです。

ネイティブ CRM の高度な検索では、現在のユーザーのタイム ゾーンが何であれ、SQL クエリを実行する前に高度な検索に入力された時間を UTC に変換します。プラグイン コントロールも同じことを行う必要があります。これらは、条件を Fetch Xml / Linq Expression / Query Expression に入れる前に実行する必要がある手順です。

  1. SystemUserId を介してユーザーの UserSetting.TimeZoneCode を取得します。
  2. ステップ 1 の TimeZoneCode の TimeZoneDefinition.StandardName を検索します。
  3. TimeZoneInfo.FindSystemTimeZoneById() を呼び出して、ステップ 2 の標準名を渡します (ステップ 1 と 2 を 1 つのクエリに組み合わせることができますが、パフォーマンスをわずかに改善するために、ステップ 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;
}
于 2012-07-06T18:09:16.037 に答える