【发布时间】:2012-09-20 03:21:18
【问题描述】:
鉴于 CRM 2011 linq 提供程序在幕后自动执行分页。 有没有办法设置 linq 时获取的记录数的上限 执行查询(类似于在 QueryExpression 上设置 PagingInfo.Count 以进行分页)
我有一个场景,我需要提取大约 20K+ 记录进行更新(不,我不能也不需要进一步过滤记录集)。理想情况下,我更喜欢使用 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
}
}
【问题讨论】:
-
为什么不一次提取所有 20,000 条记录进行更新?无论如何,CRM 将一次请求这些记录 5,001 条记录。
-
如果我必须阻止直到所有 20K 都在本地获取,那么可扩展性不是很好。我已经更新了问题以使用 Context 对象反映这一点和并行性考虑