在没有OrderBy的情况下从Entity Framework数据库中挑选随机记录

Yod*_*oda 6 c# linq entity-framework

我尝试从数据库中获取随机记录:

 personToCall = db.Persons.Skip(toSkip).Take(1).First();
Run Code Online (Sandbox Code Playgroud)

但我得到例外,告诉我:

{"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."}
Run Code Online (Sandbox Code Playgroud)

我可以不用OrderBy吗?对数据结构(O(nlogn))进行排序以选择随机元素(应该是常量)看起来并不明智.

编辑:我使用Entity Framework 6.1.1.

Dar*_*der 23

你可以有类似的东西:

personToCall = db.Persons.OrderBy(r => Guid.NewGuid()).Skip(toSkip).Take(1).First();
Run Code Online (Sandbox Code Playgroud)

你应该使用FirstOrDefault模式防御.

在这里,黑暗的领主向尤达教授力量!世界是什么来的!

  • 哈哈,最后一行太搞笑了 (6认同)

Ali*_*avi 6

首先,您需要从1到最大记录获得随机数,请参阅此内容

Random rand = new Random();
int toSkip = rand.Next(1, db.Persons.Count);

db.Persons.Skip(toSkip).Take(1).First();
Run Code Online (Sandbox Code Playgroud)

你有订单可以使用Guid.NewGuid()

db.Persons.OrderBy(x=>x.Guid.NewGuid()).Skip(toSkip).Take(1).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

  • 这很简单,但它应该是rand.Next(0,...)或永远不会包含第一条记录 (2认同)

Dav*_*kle 5

没有排序子句就无法做到这一点。

personToCall = db.Persons.OrderBy(r => Random.Next()).First();

这可能会很慢,具体取决于 Persons 表的大小,因此如果您想加快速度,则必须向 Person 添加一列,或将其加入随机数和 Person 键的字典,然后按此排序. 但这很少是明智的解决方案。

最好就手头的整体任务提出更高级别的问题。