【问题标题】:How to efficiently retrieve a list of random elements from an IQueryable?如何有效地从 IQueryable 中检索随机元素列表?
【发布时间】:2014-07-13 12:09:30
【问题描述】:

我看过以下内容:

Random element of List<T> from LINQ SQL

我现在正在做的 - 获取三个随机元素 - 如下:

var user1 = users.ElementAt( rand.Next( users.Count() ) );
var user2 = users.Where(u => !u.Equals(user1)).ElementAt( rand.Next( users.Count() ) );
var user3 = users.Where(u => !u.Equals(user1) && !u.Equals(user2)).ElementAt( rand.Next( users.Count() ) );

但这显然是笨重且低效的。我怎样才能通过一次访问数据库优雅而有效地做到这一点?

编辑:根据下面的答案,我做了以下扩展方法:

    public static IQueryable<T> SelectRandom<T>(this IQueryable<T> list, int count) {
        return list.OrderBy(_ => Guid.NewGuid()).Take(count);
    }    

    var result = users.SelectRandom(3);

但是对于大型数据集,这似乎效率低下。另一个建议是采用 IQueryable 的 .Count(),选择 n 个属于该结果的随机数,然后使用选定的随机索引向 db 发起查询......但 Count() 在这里可能很昂贵。

【问题讨论】:

  • @IanMercer 我不是在问如何随机订购,而是在问如何随机选择 n 个。

标签: c# linq entity-framework


【解决方案1】:

以下应该有效:

users.OrderBy(_ => Guid.NewGuid()).Take(3)

这会从 users 表中检索前 3 个元素,同时按每次不同的值对它们进行排序。

与 AD.Net 的答案相比.. 好吧,您需要一个随机生成的用户 ID 列表.. 它没有建议这样做的方法

【讨论】:

  • 有趣...您介意解释一下这是如何工作的,以及它与其他答案的比较吗?
  • @RobVious NewGuid() 会生成一个新的随机 GUID,因此当您按它排序时,您会得到一个随机排序,并且每次执行该行时都会有所不同。
  • 不错!我用扩展方法更新了我的问题。
  • 对于 100 万用户表来说看起来很酷。 (我们在这里执行一些 SQL)有一个词“高效”有问题,我们正在为每个用户生成 GUIDS,然后对所有这些字符串进行排序,并从这个漂亮的列表中取出 3 个。
  • @ValentinKuzub - 我的数据库包含
猜你喜欢
  • 1970-01-01
  • 2012-08-30
  • 2018-08-17
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多