2012-02-26 3 views
45

Как я могу изменить ниже код, каждый раз получать 50 различных случайных данных из базы данных?linq: заказать по производителю

return (from examQ in idb.Exam_Question_Int_Tbl 
     where examQ.Exam_Tbl_ID==exam_id 
     select examQ).OrderBy(x=>x.Exam_Tbl_ID).Take(50); 

ответ

87

http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx

return (from examQ in idb.Exam_Question_Int_Tbl 
     where examQ.Exam_Tbl_ID==exam_id 
     select examQ).OrderBy(x => Guid.NewGuid()).Take(50); 

Если это LINQ к SQL можно просто добавить к вашему ORDER BY NEWID() ЗЕЬЕСТУ.

Как прокомментировал это может быть лучше использовать алгоритм, как Fisher-Yates Shuffle, вот реализация: https://stackoverflow.com/a/375446/284240

+0

Я не думаю, что это будет работать с базой данных в любом случае (без перевода на SQL), и в итоге это будет O (nlogn). В любом случае ваш компаратор должен обеспечить полное упорядочение (это не так). Вы можете исправить это, выбирая новый GUID (один раз) для каждого элемента, а затем сортируя его, но Fisher-Yates Shuffle (версия Durstenfeldt) - лучший выбор, если вы делаете случайный выбор в памяти. – tvanfosson

+8

-1 http://blogs.msdn.com/b/ericlippert/archive/2011/01/20/spot-the-defect-bad-comparisons-part-one.aspx. во времени t: A> B истинно из-за вашего 'x => Guid.NewGuid()'. в момент времени t + n: A Guid.NewGuid()'. Функции сортировки не предназначены для перетасовки вещей, и это может привести к бесконечному циклу в худшем случае. –

+0

Чтобы расширить свое предложение, '.Select (x => new {Guid = Guid.NewGuid, Question = x}) .OrderBy (x => x.Guid). Выберите (x => x.Question) .Take (50); 'будет работать для выбора в памяти, но вы должны отсортировать его, что в среднем O (nlogn) для лучших алгоритмов. Алгоритм Durstenfeldt работает, беря коллекцию и обменивая каждый элемент в свою очередь со случайным элементом в коллекции, который вы еще не повторили. Это обеспечивает случайное упорядочение, но требует только O (n) операций. – tvanfosson

9

Насколько велика коллекция? Можете ли вы выбрать их все в памяти, а затем выбрать случайную коллекцию? Если да, то алгоритм Shuffle в Is using Random and OrderBy a good shuffle algorithm? будет хорошим выбором.

return idb.Exam_Question_Int_Tbl 
      .Where(e => e.Exam_Tbl_ID == exam_id) 
      .ToList() 
      .Shuffle() 
      .Take(50); 

Если нет, то я хотел бы предложить хранимую процедуру, которая делает заказ на newid() (SQL Server Random Sort). Я не думаю, что есть какой-либо способ перевести выражение на основе генератора случайных чисел в C# в LINQ to SQL/Entities.

+1

Что случилось с комбинацией пропустить и принять? – gdoron

3

Если у Вас есть такая же проблема, я имел ...

int Limit = 24; 
return (from Q in Context.table 
where Q.some_key == 1234 
select new classDataType() { 
    FirstAttribute = Q.FirstCol, 
    SecondAttribute = Q.SecondCol, 
    ThirdAttribute = Q.ThirdCol 
}).ToList().OrderBy(x => Guid.NewGuid()).Take(Limit).ToList(); 

После SQL-LINQ он должен быть список, поэтому, возможно, U нуждаются в изменении в список, прежде чем вы с помощью OrderBy-NewGuid-Method:

return (...-SQL-SELECT-LINQ-...) 
    .ToList() //**** 
    .OrderBy(x => Guid.NewGuid()).Take(Limit).ToList(); 
Смежные вопросы