レコードのランダムなセットを返すLinqメソッド

c# linq methods random sql-server-2008
レコードのランダムなセットを返すLinqメソッド

私はこの機能があります:

///
/// Returns an array of random articles, ID and titles only
///
/// Section ID to return
/// Number of articles to return
///
public ArticleOverview[] RandomArticles(int SectionID, int Count)
{
    ArticleOverview[] ReturnLinks;

    // Pick a random tutorial and redirect to it
    using (MainContext db = new MainContext())
    {
        // Select rows
        var q = (from c in db.tblArticles where c.IsDeleted == false && c.SectionID == SectionID select new { c.ID, c.Title });
        int count = q.Count();
        int index = new Random().Next(count);
        var Articles = q.Skip(index).Take(Count);

        // Size array
        ReturnLinks = new ArticleOverview[Articles.Count()];

        int InsertIx = 0;
        foreach (var Rec in Articles)
        {
            ReturnLinks[InsertIx] = new ArticleOverview(Rec.ID, Rec.Title, SectionID);
            InsertIx++;
        }
    }

    return ReturnLinks;
}

この方法には2つの問題があります。

  • 最後のレコードの1つを選択すると、_less_レコードを返します
    IE、レコードセットカウントが100で、10個のレコードを選択し、インデックス95を返す場合、IEは10個ではなく5個のレコードのみを返します

  • 返されたレコードは順序付けられており、混乱していません。 返された
    レコードは、データベースに順番に存在するため、ランダム化する必要があり、順序付けする必要はありません。

助けてくれてありがとう! SQL Server Express 2008 R2を使用しています。

  1  0


ベストアンサー

LinqからSqlへのランダムな行のメソッドを使用して、「orderby ctx.Random()」を実行し、 FirstOrDefault`の代わりに結果に対して .Take(sampleSize) `

4


結果をどの程度ランダムにする必要がありますか?

さて、「q」から新しい匿名のランダム値を選択し、その後、その乱数で並べ替えて、トップカウントを選択できます。 明らかな欠点は、選択をdbに委任する代わりに、すべての記事をメモリに読み込む必要があることです。

0


別の潜在的な問題は、現在の方法が同じ確率で各レコードを選択しないことです。 それを確認する簡単な方法は、10個のレコードのうち9個が望ましいと仮定することです。 現在の方法では、最初のレコードを選択する可能性は10%しかありませんが、常に10番目のレコードが選択されます。

レコード番号のランダムなセット(https://stackoverflow.com/questions/254844/random-array-using-linq-and-c [この投稿で説明]など)を生成する方が良いようです。 次に、それらを使用して、結果セットからそれらのエントリを選択します。

0


1 . ランダムクラスインスタンスを定義して、「よりランダム」にする

2 . 次のコードを使用して、ランダムな要素を選択します

var result = Enumerable.Range(0, count).OrderBy(a => Rand.Next()).Take(resCount).Select(i => q[i]);

0


タイトルとURLをコピーしました