CRM2011linqプロバイダーが舞台裏で自動的にページングを実行することを考えると。linqクエリの実行時にフェッチされるレコード数の上限を設定する方法はありますか(ページング用のQueryExpressionでPagingInfo.Countを設定するのと同様)
更新のために約2万件以上のレコードをプルする必要があるシナリオがあります(レコードセットをさらにフィルタリングすることはできませんし、必要もありません)。理想的には、Skip&Take演算子を使用することをお勧めしますが、Countはサポートされていないため、スキップするレコードの数と、さらにレコードのフェッチを停止するタイミングをどのように知ることができますか。
理想的には、TPLを使用し、たとえば3Kまたは5Kレコードのバッチを並行して処理して、スループットを向上させ、ブロックする必要がないようにします。OrganizationserviceContextは、私が知っていることからスレッドセーフではありません。この場合、Parallel.ForまたはParallel.ForEachを使用してデータセットを分割する方法を示す良い例はありますか?どのようにパーティションを作成し、パーティションごとに異なるコンテキストオブジェクトを使用する必要がありますか?
ありがとう。
更新:これが私が思いついたものです:アイデアは、処理するレコードの総数を取得し、PLINQを使用して、タスクごとに新しいOrganizationServiceContextオブジェクトを使用してタスク全体のデータの各サブセットの処理をファームアウトすることです。
static void Main(string[] args)
{
int pagesize = 2000;
// use FetchXML aggregate functions to get total count
// Reference: http://msdn.microsoft.com/en-us/library/gg309565.aspx
int totalcount = GetTotalCount();
int totalPages = (int)Math.Ceiling((double)totalcount / (double)pagesize);
try
{
Parallel.For(0, totalPages, () => new MyOrgserviceContext(),
(pageIndex, state, ctx) =>
{
var items = ctx.myEntitySet.Skip((pageIndex - 1) * pagesize).Take(pagesize);
var itemsArray = items.ToArray();
Console.WriteLine("Page:{0} - Fetched:{1}", pageIndex, itemsArray.Length);
return ctx;
},
ctx => ctx.Dispose()
);
}
catch (AggregateException ex)
{
//handle as needed
}
}