C# 不带GUID的Linq随机顺序
需要使用linq随机排序,而我不能使用GUID.NewGuid(),我需要如下内容:.OrderBy(x=>“somestring”) 假设一个移动应用程序生成一个随机字符串并调用我的WebApi,因为我维护了寻呼,所以移动应用程序将发送相同的随机字符串,但不同的页码,所以每次发送时,随机字符串的顺序应该相同但不同 这怎么可能?如果不是一个字符串,但可能是一个数字或任何固定的linq查询 编辑: 这是WebApiC# 不带GUID的Linq随机顺序,c#,linq,random,C#,Linq,Random,需要使用linq随机排序,而我不能使用GUID.NewGuid(),我需要如下内容:.OrderBy(x=>“somestring”) 假设一个移动应用程序生成一个随机字符串并调用我的WebApi,因为我维护了寻呼,所以移动应用程序将发送相同的随机字符串,但不同的页码,所以每次发送时,随机字符串的顺序应该相同但不同 这怎么可能?如果不是一个字符串,但可能是一个数字或任何固定的linq查询 编辑: 这是WebApi [Route("GetChannels/{id}/{word}/{page}/{r
[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();
}
...
[路由(“GetChannels/{id}/{word}/{page}/{randomstring}”)]
公共IEnumerable GetChannel(整数id、字符串字、整数页、字符串随机字符串)
{
...
如果(canPage)
{
var channels=db.channels.Where(x=>(id==0)| |(x.CategoryId==id))
。其中(q=>word==“0”||
(q.Title.Contains(word)| q.Desc.Contains(word)))
.OrderBy(x=>randomstring).Skip(Skip).Take(pageSize).ToList();
}
...
试试这样的方法
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);
Random rand=new Random();
列表输入=新列表();
var results=input.Select(x=>new{x=x,r=rand.Next()}).OrderBy(x=>x.r).Select(x=>x.x);
试试这样的方法
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);
Random rand=new Random();
列表输入=新列表();
var results=input.Select(x=>new{x=x,r=rand.Next()}).OrderBy(x=>x.r).Select(x=>x.x);
如果您希望以随机顺序返回结果,但如果您从客户端发送相同的字符串,则该顺序将是相同的,那么您可以使用类来获取伪随机顺序。此随机生成器可以接受seed-a值,该值用于计算伪随机序列的起始值。因此,您正在传递字符串使用其哈希代码获取种子的整数值:
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();
如果您希望以随机顺序返回结果,但如果您从客户端发送相同的字符串,则该顺序将是相同的,那么您可以使用类来获取伪随机顺序。此随机生成器可以接受seed-a值,该值用于计算伪随机序列的起始值。因此,您可以使用获取种子的整数值是哈希代码:
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();
接受@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较大,则性能可能会很差
实际上,在大多数情况下,我建议使用一个随机数,生成未分页的结果,然后使用该键将结果填充到缓存中,用于后续的分页操作(如果无法将整个未分页结果发送到客户端).接受@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较大,则性能可能会很差
实际上,在大多数情况下,我建议使用一个随机数,生成未分页的结果,然后使用该键将结果填充到缓存中,用于后续的分页操作(如果无法将整个未分页结果发送到客户端).您能在问题描述中添加一些标点符号吗?正如它目前所写的那样,不清楚您现在有什么,如何调用api,以及您希望得到什么。我能问一下您为什么想要GUID吗?我想Jon Skeet的回答使用了GUIDs@SergeyBerezovskiy,我补充了更多details@farhang67.OrderBy(x=>randomstring)
将返回无序序列,因为所有项目的randomstring
都是相同的。你能描述一下你想要实现什么吗?@SergeyBerezovskiy我想在移动应用程序用户每次打开应用程序时以随机顺序向他们显示结果,这样我就可以生成一些用于订购的字符串,并在他们翻页应用程序时发送给服务器将发送相同的字符串,因此排序将相同,但页码不同…您可以在问题描述中添加一些标点符号吗?由于目前编写的内容不清楚您现在有什么,如何调用api,以及您希望获得什么我可以问一下为什么要使用GUID吗?我认为Jon Skeet的答案使用了GUIDs@SergeyBerezovskiy,我补充了更多details@farhang67.OrderBy(x=>randomstring)
将返回无序序列,因为所有项目的randomstring
都是相同的。你能描述一下你想要实现什么吗?@SergeyBerezovskiy我想在移动应用程序用户每次打开应用程序时以随机顺序向他们显示结果,这样我就可以生成一些用于订购的字符串,并在他们翻页应用程序时发送给服务器将发送相同的字符串,因此排序将是相同的,但页码不同…这是一个不错的解决方案,但需要注意的是,如果列表在第一次调用和任何后续分页调用之间发生任何更改,则列表将完全更改。因此,如果您看到某些经常更改的内容,这将不会很好地工作。实际上,由于如果未指定任何orderby
,大多数数据库都不能保证顺序,因此如果未更改任何记录,则很有可能达到收支平衡…您可以通过将.orderby(x=>x.id)
放在.AsEnumerable()之前来解决后面的问题
@RobertMcKee,很遗憾,这将不起作用。您无法处理添加项目和保存原始项目的原始顺序。例如,您有项目1,2,3
。这些项目的顺序为2,1,3
。又添加了一个项目。您想保留原始顺序并返回2,1,3,4
。下一个项目来了。您想保留吗原始订单,您得到2,1,