2

リストから指定された数のランダムなレコードを取得する関数を作成しました。現在、私は次のようなことができます:

IEnumerable<City> cities = db.Cites.GetRandom(5);

(ここで、db は SQL Server DB に接続している私の DataContext です)

現在、ランダムレコードが必要なすべてのエンティティに次のような関数があります。

public partial class City
{

    public static IEnumerable<City> GetRandom(int count)
    {
        Random random = new Random();
        IEnumerable<City> cities = DB.Context.Cities.OrderBy( c => random.Next() ).Take(count);

        return cities;
    }

}

それは正常に動作しますが、一般的なものにしたいので、どのテーブルでも、どのアイテムのリストでも動作します。次のような拡張メソッドを試しました:

    public static IEnumerable<T> GetRandom<T>( this Table<T> table, int count)
    {
        Random random = new Random();
        IEnumerable<T> records = table.OrderBy(r => random.Next()).Take(count);

        return records;
    }

しかし、私は得る:

  エラー 1 型 'T' は、ジェネリック型またはメソッド 'System.Data.Linq.Table' でパラメーター 'TEntity' として使用するには、参照型である必要があります 

ハイライトしますGetRandom<T>

ここで何が問題なのかわかりません。誰かが適切な構文をクリアできますか?

4

4 に答える 4

6

私はランダムな順序関数のアイデアが好きで、次のように任意の IEnumerable に適用できます。

public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
{
    Random rnd = new Random();
    return source.OrderBy(t => rnd.Next());
}

...

IEnumerable<City> cities = db.Cites.Randomize().Take(5);
于 2008-12-09T08:00:08.533 に答える
5

データベースと話している場合は、データベースでランダム フェッチを実行することをお勧めします。LINQ-to-SQL を使用すると、(データ コンテキストで) NEWID を指す [関数] を介してこれを行うことができます (小規模なボリュームの場合)。

     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { 
         return Guid.NewGuid(); 
     } 

次に、次のクエリで:

     ctx.Log = Console.Out; 
     var query = from x in ctx.Suppliers 
                 orderby ctx.Random() 
                 select x; 
     var results = query.ToArray(); 

これにより、TSQLが得られます(ここではNorthwindを使用):

SELECT [t0].[SupplierID], [t0].[CompanyName], [t0].[ContactName], 
[t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], 
[t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax], [t0].[HomePage] 
FROM [dbo].[Suppliers] AS [t0] 
ORDER BY NEWID() 

明らかに、これを Take(1) などと組み合わせることができます。

ただし、エンティティ フレームワークでは機能しません。

于 2008-12-09T08:42:54.843 に答える
4

JaredPar、一般的な定義内の:classでそれを行うことはできないと思います。

これが型制約を定義する適切な方法だと思います。

public static IEnumerable<T> GetRandom<T>( this Table<T> table, int count) where T : class {
  ...
}

タイプ制約の詳細については、こちらをご覧ください

于 2008-12-09T06:13:19.263 に答える
0

これを試して

public static IEnumerable<T> GetRandom<T>( this Table<T> table, int count) where T : class {
  ...
}
于 2008-12-09T06:06:19.153 に答える