linq:随机排序

问题描述 投票:0回答:4

如何更改下面的代码,以便每次从数据库中获取 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);
c# linq random
4个回答
126
投票

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,您只需在 SELECT 语句中添加

ORDER BY NEWID()
即可。

正如评论所述,使用像 Fisher-Yates Shuffle 这样的算法可能会更好,这里是一个实现:https://stackoverflow.com/a/375446/284240


10
投票

馆藏有多大?您可以将它们全部选择到内存中,然后随机选择一个集合吗?如果是这样,那么使用 Random 和 OrderBy 是一个好的 shuffle 算法吗? 中的 Shuffle 算法将是一个不错的选择。

return idb.Exam_Question_Int_Tbl
          .Where( e => e.Exam_Tbl_ID == exam_id )
          .ToList()
          .Shuffle()
          .Take( 50 );

如果没有,那么我建议使用一个存储过程,通过

newid()
SQL Server 随机排序)进行排序。我认为没有任何方法可以将 C# 中基于随机数生成器的表达式转换为 LINQ to SQL/Entities。


5
投票

如果你有同样的问题,我有......

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 之后,它需要是一个列表,所以在使用 OrderBy-NewGuid-Method 之前,您可能需要更改为列表:

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

0
投票

Entity Framework Core 6+ 新增了一个功能:

EF.Functions.Random()

db.Table.Where(...).OrderBy(r => EF.Functions.Random()).Take(50)

这种方法的优点是它使用了数据库引擎的内部功能,并且已经为大多数数据库实现了。

参见https://github.com/dotnet/efcore/issues/16141#issuecomment-666641607

© www.soinside.com 2019 - 2024. All rights reserved.