2017-04-14 42 views
0

需要随机使用linq命令,我不能使用GUID.NewGuid(),我需要这样的东西:.OrderBy(x =>“somestring”)。林奇顺序随机没有GUID

假设一个移动应用程序生成一个随机字符串,并调用我的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(); 
     } 

... 
+0

您可以在问题描述中添加一些标点符号吗?正如它目前所写的,目前还不清楚你现在拥有什么,你如何调用api,以及你期望得到什么 –

+0

我能问你为什么想要GUID吗?我认为Jon Skeet的答案使用GUID –

+0

@SergeyBerezovskiy,我添加了更多细节 – farhang67

回答

1

,但该订单将是相同的,如果您从客户端发送相同的字符串,然后您可以使用Random类来获得伪随机顺序。这个随机发生器可以接受种子 - 一个值,用于计算伪随机序列的起始值。因此,你逝去的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();  
+0

一个不错的解决方案,但有一点需要注意的是,如果列表在第一次调用和后续的任何寻呼呼叫之间完全改变,那么列表将完全改变。所以如果你正在寻找经常变化的东西,这将不会很好。实际上,如果没有指定'orderby',大多数数据库都不能保证顺序,即使没有记录被改变,这也很可能会中断... –

+0

您可以通过将'.OrderBy(x = > .AsEnumerable()'之前的> x.id)。 –

+0

@RobertMcKee,不幸的是,这将无法正常工作。您无法处理添加项目并保存原始项目的原始顺序。例如。你有物品'1,2,3'。其中被命令为“2,1,3”。又增加了一个项目。你想保留原来的顺序并返回'2,1,3,4'。下一个项目来。你想保留原来的顺序,你会得到'2,1,3,4,5'。即所有未来的物品都不会被洗牌。他们将按照他们添加的顺序返回。 –

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); 
1

以@谢尔盖的已经很优秀的答案和解决一些小角落里的情况:

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很大,性能可能会很差。实际上,对于大多数情况下,我只是建议使用随机数,生成未分页的结果,然后使用该键将结果填充到高速缓存中以用于后续分页操作(如果将未分页的整个结果发送到客户端不是选项)。