linq: ordre par aléatoire

Comment puis-je changer le code ci-dessous, pour obtenir à chaque fois 50 données aléatoires différentes de la base de données?

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);
48
demandé sur Matthew Lock 2012-02-26 04:31:02

3 réponses

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);

S'il S'agit de LINQ-to-SQL, vous pouvez simplement ajouter un ORDER BY NEWID() à votre instruction SELECT.

Comme commenté, il pourrait être préférable d'utiliser un algorithme comme Fisher-Yates Shuffle , Voici une implémentation: https://stackoverflow.com/a/375446/284240

93
répondu Tim Schmelter 2017-05-23 10:31:12

Quelle est la taille de la collection? Vous pouvez sélectionner tous en mémoire puis choisissez une collection aléatoire? Si oui, alors l'algorithme de lecture aléatoire à utilise Random et OrderBy un bon algorithme de lecture aléatoire? serait un bon choix.

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

Si ce n'est pas le cas, je suggérerais une procédure stockée qui effectue une commande par newid() ( SQL Server Random Sort ). Je ne pense pas qu'il existe un moyen de traduire une expression basée sur un générateur de nombres aléatoires en C# en LINQ en SQL/Entities.

9
répondu tvanfosson 2017-05-23 11:47:19

Si vous avez le même problème, j'ai eu...

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();

Après sql-linq, il doit s'agir d'une liste, alors peut-être avez-vous besoin de passer à une liste, avant d'utiliser la méthode OrderBy-NewGuid:

return (...-SQL-SELECT-LINQ-...)
    .ToList() //****
    .OrderBy(x => Guid.NewGuid()).Take(Limit).ToList();
3
répondu Froschkoenig84 2017-09-12 16:12:51