エンティティへのリンク、ランダムな順序

c# entity-framework linq-to-entities

質問

一致するエンティティをランダムな順序で返す方法
明確にするために、これはEntity FrameworkのものとLINQ to Entitiesです。

(エアーコード)

IEnumerable<MyEntity> results = from en in context.MyEntity
                                where en.type == myTypeVar
                                orderby ?????
                                select en;

ありがとう

編集する
これをコンテキストに追加してみました。

public Guid Random()
{
    return new Guid();
}

そして、このクエリを使用して:

IEnumerable<MyEntity> results = from en in context.MyEntity
                                where en.type == myTypeVar
                                orderby context.Random()
                                select en;

しかし、私はこのエラーを得ました:

System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Guid Random()' method, and this method cannot be translated into a store expression..

編集(現在のコード):

IEnumerable<MyEntity> results = (from en in context.MyEntity
                                 where en.type == myTypeVar
                                 orderby context.Random()
                                 select en).AsEnumerable();

受け入れられた回答

簡単な解決策は、配列(またはList<T> )を作成し、そのインデックスをランダム化することです。

編集:

static IEnumerable<T> Randomize<T>(this IEnumerable<T> source) {
  var array = source.ToArray();
  // randomize indexes (several approaches are possible)
  return array;
}

編集:個人的には、私はJon Skeetの答えがもっとエレガントだと思う。

var results = from ... in ... where ... orderby Guid.NewGuid() select ...

そして、確かに、あなたはGuid.NewGuid()代わりに乱数ジェネレータを取ることができます。


人気のある回答

これを行う簡単な方法はGuid.NewGuid()注文することですが、その後、注文はクライアント側で行われます。 EFがサーバー側でランダムに何かをするように説得することはできるかもしれませんが、それは必ずしも単純ではありません - そして、 "乱数順"を使ってそれを行うことは明らかに壊れています。

順序付けをEFではなく.NET側で行わせるには、 AsEnumerableが必要AsEnumerable

IEnumerable<MyEntity> results = context.MyEntity
                                       .Where(en => en.type == myTypeVar)
                                       .AsEnumerable()
                                       .OrderBy(en => context.Random());

順序付けされていないバージョンをリストに入れてから、それをシャッフルすることをお勧めします。

Random rnd = ...; // Assume a suitable Random instance
List<MyEntity> results = context.MyEntity
                                .Where(en => en.type == myTypeVar)
                                .ToList();

results.Shuffle(rnd); // Assuming an extension method on List<T>

シャッフリングは、ソート以外にも、ソートよりも効率的です。適切なRandomインスタンスを取得する方法の詳細については、私のランダム性に関する記事を参照してください 。 Stack OverflowにはたくさんのFisher-Yatesシャッフル実装があります。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ