Linq命令随机没有GUID

时间:2017-04-14 15:08:57

标签: c# linq random

需要使用linq随机排序,我不能使用GUID.NewGuid(),我需要这样的东西:.OrderBy(x =>" somestring")。

一个移动应用程序假设生成一个随机字符串并调用我的WebApi,因为我保持分页移动应用程序将发送相同的随机字符串但不同的页码,所以每次发送该随机字符串顺序应该相同但不同跳过....

这怎么可能?如果不是一个字符串,但可能是一个数字或任何固定的每个linq查询。

编辑:

这是WebApi

[Route("GetChannels/{id}/{word}/{page}/{randomstring}")]
public IEnumerable<Channels> GetChannels(int id, string word, int page, string randomstring)
    {

   ...

    if (canPage)
       {                
            var channels = db.Channels.Where(x => (id == 0) || (x.CategoryId == id))
            .Where(q => word == "0" ||
            (q.Title.Contains(word) || q.Desc.Contains(word)))
            .OrderBy(x => randomstring).Skip(skip).Take(pageSize).ToList();
        }

...

3 个答案:

答案 0 :(得分:2)

如果要以随机顺序返回结果,但如果从客户端发送相同的字符串,则该顺序将相同,则可以使用Random类来获取伪随机顺序。该随机生成器可以接受 seed - 一个值,用于计算伪随机序列的起始值。因此,您传递string,您可以使用它的哈希码来获取种子的整数值:

        var seed = randomstring.GetHashCode();
        var random = new Random(seed);

        var channels = db.Channels
           .Where(x => (id == 0) || (x.CategoryId == id))
           .Where(q => word == "0" || (q.Title.Contains(word) || q.Desc.Contains(word)))
           .AsEnumerable() // randomizing should happen on client side
           .OrderBy(x => random.Next())
           .Skip(skip)
           .Take(pageSize)
           .ToList();    

答案 1 :(得分:1)

采取@ Sergey已经很好的答案并解决了一些小问题:

    var channels = db.Channels.AsQueryable();

    #region filtering
      if (id!=0)
        channels = channels.Where(x=>x.CategoryId == id);
      if (word!="0")
        channels = channels.Where(x=>x.Title.Contains(word) || x.Desc.Contains(word));
    #endregion filtering

    #region server-side ordering
      channels = channels.OrderBy(x=>x.id);
    #endregion server-side ordering

    #region client-side ordering
      var seed = randomstring.GetHashCode();
      var random = new Random(seed);
      var channelList = channels.ToList(); // force client side
      var maxid = channelList.Select(x=>id).Max();
      var keys = Enumerable
        .Range(0,maxid)
        .ToDictionary(x=>x,x=>random.Next());

      var sorted = channelList
        .OrderBy(x=>keys[x.id]);
    #endregion client-side ordering

    #region paging
      var results = sorted
        .Skip(skip)
        .Take(pageSize)
        .ToList();
    #endregion paging

在这种情况下,如果添加了一条记录(新的更高的ID),或删除了(删除了ID),那么该订单将被维护,就像记录始终存在一样,因此结果可能会改变,但不会完全重新排序。如果频道的ID很大,性能也可能会很差。

实际上,对于大多数情况,我建议使用随机数,生成未分页的结果,然后使用该密钥将结果填充到缓存中以用于后续的分页操作(如果将未分配的整个结果发送到客户端则不是一个选项)。

答案 2 :(得分:0)

尝试这样的事情

Random rand = new Random();
            List<string> input = new List<string>();
            var results = input.Select(x => new { x = x, r = rand.Next() }).OrderBy(x => x.r).Select(x => x.x);