Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picking random record from Entity Framework database without OrderBy

I try to get random record from database:

 personToCall = db.Persons.Skip(toSkip).Take(1).First();

but I get exception which tells me:

{"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."}

Can I do it without OrderBy? Sorting data structure (O(nlogn)) to pick random element(which should be constant) doesn't look wise.

EDIT: I use Entity Framework 6.1.1.

like image 843
Yoda Avatar asked Sep 14 '14 16:09

Yoda


3 Answers

You can have something like :

personToCall = db.Persons.OrderBy(r => Guid.NewGuid()).Skip(toSkip).Take(1).First();

You should use FirstOrDefault to be mode defensive.

Here the dark lord teaching the force to yoda! what is the world coming to!

like image 89
DarthVader Avatar answered Jan 27 '23 04:01

DarthVader


First you need to get the random number from 1 to max record, see this

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

db.Persons.Skip(toSkip).Take(1).First();

with order by you can use the Guid.NewGuid()

db.Persons.OrderBy(x=>x.Guid.NewGuid()).Skip(toSkip).Take(1).FirstOrDefault();
like image 25
Ali Adravi Avatar answered Jan 27 '23 03:01

Ali Adravi


There is no way to do this without an ordering clause.

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

That could be slow depending on the size of your Persons table, so if you wanted to make this fast, you'd have to add a column to Person, or join it to a dictionary of random numbers and Person keys, then order by that. But that is rarely a wise solution.

Better to ask a higher level question about the overall task at hand.

like image 43
Dave Markle Avatar answered Jan 27 '23 05:01

Dave Markle