Dynamics CRM 2011: LINQ クエリで Distinct メソッドを利用した場合に、エラーが発生することがある

みなさん、こんにちは。

今回は開発者の方向けの情報として、LINQ クエリに関する既知の
問題とその対応方法について紹介します。

問題

LINQ クエリで Distinct() メソッドを利用した場合に、結果セットに
5000 件以上のレコードが返った場合、以下のエラーが発生します。

クエリの例
var query_distinct = (from a in svcContext.AccountSet
                               select a.Name).Distinct();

Paging cookie required to retrieve more records. Update your query to retrieve with total records below 5000

原因

LINQ は 5000 件以上の結果についても自動的にページングする
機能があるため、以下のようなクエリの場合、意識することなく
5000 件以上の結果を返すことが出来ます。

var query_distinct = (from a in svcContext.AccountSet
                               select a.Name);

ただし Distinct のように結果セットを別途確認する必要があるクエリに
ついては、5000 件の上限が問題となります。

対応方法

以下の対応策が考えられます。

対応策 1
Where() メソッドを利用して結果セットを絞り込む。ただし結果セットが
5000 件を超えるとエラーが発生します。

対応策 2
Take(5000) を利用する。結果が 5000 件以上ある場合、5000 件以降
については考慮されません。尚、Skip() メソッドと併用することも可能
ですが、Skip は 5000 以上の値は指定できません。

対応策 3
大量に結果セットがあることが分かっている場合、Distinct を利用せず
結果を一旦 DataSet に保持し、その後結果セットを別途操作する。

参考情報

FetchXML や QueryExpression でのページング情報は以下の URL を
ご参照ください。

クエリ式を使用して大きな結果セットをページングする
https://msdn.microsoft.com/ja-jp/library/gg327917.aspx

FetchXML による大量の結果セットのページング
https://msdn.microsoft.com/ja-jp/library/gg309717.aspx

- Dynamics CRM サポート 中村 憲一郎