【问题标题】:Linq Orderby random ThreadSafe for use in ASP.NETLinq Orderby 随机 ThreadSafe 用于 ASP.NET
【发布时间】:2011-03-21 07:58:07
【问题描述】:

我正在使用带有 Sharp 架构的 Asp.net MVC。

我有这个代码:

return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
                .Take(50).ToList();

如何随机订购? 注意:我不想订购提取的 50 件商品,我想先订购然后提取 50 件商品。

谢谢

【问题讨论】:

  • 您是说您希望整个列表随机化,然后您想检索前 50 个项目?
  • 这个问题不重复链接的问题。这个问题专门表示需要 ThreadSafe 随机访问的 ASP.NET。链接的问题没有提到 ThreadSafe

标签: asp.net asp.net-mvc linq s#arp-architecture


【解决方案1】:
Random random = new Random();
return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
                .OrderBy(x => r.Next())
                .Take(50).ToList();

【讨论】:

  • 哈,我喜欢这样。如果它使用快速排序,那可能会崩溃。我知道尝试对不一致的参数使用 Array.Sort 会导致异常。
  • 我想看看生成的sql。它是返回整个表,然后排序并丢弃除前 50 条记录之外的所有内容吗?
  • 啊,是的,应该是 .Take(50).OrderBy(x => r.Next()),而不是相反。编辑:没关系,我误读了这个问题。
  • @Rei Miyasaka:为什么,他明确表示他不想只对 50 个项目进行排序?反转它们的 SQL 是否按照规范正确生成?
【解决方案2】:

最好编写自己的扩展方法来做到这一点。

public static class Extensions
{
    static readonly Random random = new Random();

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
    {
        return Shuffle(items, random);
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items, Random random)
    {
        // Un-optimized algorithm taken from
        // http://en.wikipedia.org/wiki/Knuth_shuffle#The_modern_algorithm
        List<T> list = new List<T>(items);
        for (int i = list.Count - 1; i >= 1; i--) 
        {
            int j = random.Next(0, i);
            T temp = list[i];
            list[i] = list[j];
            list[j] = temp;
        }
        return list;
    }
}

【讨论】:

  • Random.Next 不是线程安全的,因此您不能在此处使用静态变量来存储共享的 Random 值。
  • 当然,必须有 i--,而不是 i++
【解决方案3】:

您可以按照here 的描述在 T-Sql 中执行此操作。我认为如果不将整个结果集加载到内存中然后将其中大部分扔掉,你就不能在 linq 中做到这一点,这是你不想做的。

【讨论】:

    【解决方案4】:

    一种有效实现的方法是向您的数据Shuffle 添加一列,该列填充了随机整数(在创建每条记录时)。

    访问表的查询就变成了...

    Random random = new Random();
    int seed = random.Next();
    result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);
    

    这会在数据库中执行 XOR 操作并按 XOR 的结果排序。

    优点:-

    1. 高效:SQL 处理 订购,无需获取整个 表
    2. 可重复:(适用于 测试) - 可以使用相同的随机 种子生成相同的随机数 订购
    3. 支持大多数(全部?)实体框架 数据库

    这是我的家庭自动化系统用来随机播放列表的方法。它每天挑选一个新种子,在一天中提供一致的顺序(允许轻松暂停/恢复功能),但每天都会重新审视每个播放列表。

    【讨论】:

    • 这个解决方案让我大吃一惊。
    • jfar:我也是;太棒了。虽然我只是使用 PK(它是一个 int)而不是 Shuffle 字段,但它工作得很好。感谢高科技骑士!
    • 这太棒了!我也用过PK。性能卓越
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多