我尝试从数据库中获取随机记录:
personToCall = db.Persons.Skip(toSkip).Take(1).First();
但我得到例外,告诉我:
{"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."}
我可以在没有OrderBy
的情况下执行此操作吗?对数据结构(O(nlogn))进行排序以选择随机元素(应该是常数)看起来并不明智。
编辑:我使用的是Entity Framework 6.1.1。
答案 0 :(得分:21)
您可以拥有以下内容:
personToCall = db.Persons.OrderBy(r => Guid.NewGuid()).Skip(toSkip).Take(1).First();
您应该使用FirstOrDefault
作为模式防御。
这里黑暗的领主向尤达教授力量!世界是什么来的!
答案 1 :(得分:6)
首先,您需要从1到最大记录获取随机数,请参阅此
Random rand = new Random();
int toSkip = rand.Next(1, db.Persons.Count);
db.Persons.Skip(toSkip).Take(1).First();
按顺序你可以使用Guid.NewGuid()
db.Persons.OrderBy(x=>x.Guid.NewGuid()).Skip(toSkip).Take(1).FirstOrDefault();
答案 2 :(得分:3)
没有订购条款就无法做到这一点。
personToCall = db.Persons.OrderBy(r => Random.Next())。First();
根据你的Persons表的大小,这可能会很慢,所以如果你想快速做到这一点,你必须向Person添加一个列,或者将它连接到随机数字和Person键的字典,然后按顺序排列。但这很少是一个明智的解决方案。
最好提出一个关于手头总体任务的更高层次的问题。
答案 3 :(得分:-1)
要避免使用OrderBy,请转储到List并随机选择索引:
VB
With New List(Of Persons)
.AddRange(db.Persons)
PersonToCall = .Item(New Random().Next(0, .Count - 1))
End With
C#
var people = new List<Persons>();
people.AddRange(db.Persons);
personToCall = people.Item(new Random().Next(0, people.Count - 1));