web-dev-qa-db-ja.com

linq:ランダム順

データベースから50種類のランダムデータを取得するたびに、以下のコードを変更するにはどうすればよいですか?

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

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-to-SQLの場合、ORDER BY NEWID()をSELECTステートメントに追加するだけです。

コメントしたように、 Fisher-Yates Shuffle のようなアルゴリズムを使用した方が良いかもしれません。ここに実装があります: https://stackoverflow.com/a/375446/28424

106
Tim Schmelter

コレクションの大きさは?それらをすべてメモリに選択してから、ランダムなコレクションを選択できますか?もしそうなら、 RandomとOrderByは良いシャッフルアルゴリズムを使用していますか? のシャッフルアルゴリズムが良い選択です。

_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に変換する方法はないと思います。

10
tvanfosson

あなたが同じ問題を抱えているなら、私は持っていた...

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の後、それはLISTである必要があるため、OrderBy-NewGuid-Methodを使用する前に、Uをリストに変更する必要があるかもしれません。

return (...-SQL-SELECT-LINQ-...)
    .ToList() //****
    .OrderBy(x => Guid.NewGuid()).Take(Limit).ToList();
4
Froschkoenig84