2

我编写了一个从列表中获取给定数量的随机记录的函数。目前我可以做类似的事情:

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

(其中 db 是我的 DataContext 连接到 SQL Server DB)

目前,我在每个需要随机记录的实体中都有这样的功能:

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] 执行此操作:

     [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 回答