Dynamics CRM 2011, на данный момент, не может дать вам степень запросов, которую могут предоставить SQL и другие поставщики LINQ, поэтому я действительно верю, что вы захотите сказать "нет" клиенту и перейти к локальной версии, если он / она хочет такой гибкости.
С учетом сказанного, вариант метода № 1 состоит в том, чтобы вместо выборки всех строк сразу, а затем выбрать случайный наборизвлекайте случайный набор из объекта по одной строке за раз, пока у вас не будет желаемого количества строк.Недостатком этого метода является то, что вместо одного обращения к БД их много, что замедляет общую скорость извлечения.POC ниже.
Что касается # 2, я считаю, что возможно обработать все ваши запросы, с некоторой степенью успеха, используя fetchXml.Фактически, единственный способ получить агрегированные данные - это использовать fetchXml, и он также поддерживает paging .
Что касается # 3, нативный SQL - ваш лучший выборчтобы получить все, что вы хотите, из ваших данных на данный момент, но это несмотря на то, что, хотя поставщик LINQ ограничен , гораздо проще переводить операторы SQL в LINQ, чем в fetchXML, а это делаетподдержка поздних привязок / динамических объектов .
//create a list of random numbers
List<int> randomNumbers = new List<int>();
//declare a percentage of records you'd like to retrieve
double pctg = 0.07;
//use FetchXML to count the # of rows in the table
string fetchXml = @"<fetch aggregate='true'>
<entity name='salesorder'>
<attribute name='salesorderid' aggregate='count' alias='countIds' distinct='false' />
</entity>
</fetch>";
EntityCollection result = _service.RetrieveMultiple(new FetchExpression(fetchXml));
int rowCount = int.Parse(result.Entities[0].FormattedValues["countIds"].Replace(",", ""));
//initalize the random number list for paging
for (int i = 0; i < Math.Ceiling(pctg * rowCount); i++)
{
randomNumbers.Add((new Random(unchecked((int)(DateTime.Now.Ticks >> i)))).Next(rowCount - 1));
}
randomNumbers.Sort();
//page through the rows one at a time until you have the number of rows you want
using (OrganizationServiceContext osc = new OrganizationServiceContext(_service))
{
foreach (int r in randomNumbers)
{
foreach (var er in (from c in osc.CreateQuery("salesorder")
//not especially useful to use the orderby option as you can only order by entity attributes
//orderby c.GetAttributeValue<string>("name")
select new
{
name = c.GetAttributeValue<string>("name")
}).Skip(r).Take(1))
{
Console.WriteLine(er.name);
}
}
}