Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to Entities, random order

How do i return matching entities in a random order?
Just to be clear this is Entity Framework stuff and LINQ to Entities.

(air code)

IEnumerable<MyEntity> results = from en in context.MyEntity                                 where en.type == myTypeVar                                 orderby ?????                                 select en; 

Thanks

Edit:
I tried adding this to the context:

public Guid Random() {     return new Guid(); } 

And using this query:

IEnumerable<MyEntity> results = from en in context.MyEntity                                 where en.type == myTypeVar                                 orderby context.Random()                                 select en; 

But i got this error:

System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Guid Random()' method, and this method cannot be translated into a store expression.. 

Edit (Current code):

IEnumerable<MyEntity> results = (from en in context.MyEntity                                  where en.type == myTypeVar                                  orderby context.Random()                                  select en).AsEnumerable(); 
like image 213
NikolaiDante Avatar asked Mar 17 '09 16:03

NikolaiDante


1 Answers

A simple way of doing this is to order by Guid.NewGuid() but then the ordering happens on the client side. You may be able to persuade EF to do something random on the server side, but that's not necessarily simple - and doing it using "order by random number" is apparently broken.

To make the ordering happen on the .NET side instead of in EF, you need AsEnumerable:

IEnumerable<MyEntity> results = context.MyEntity                                        .Where(en => en.type == myTypeVar)                                        .AsEnumerable()                                        .OrderBy(en => context.Random()); 

It would be better to get the unordered version in a list and then shuffle that though.

Random rnd = ...; // Assume a suitable Random instance List<MyEntity> results = context.MyEntity                                 .Where(en => en.type == myTypeVar)                                 .ToList();  results.Shuffle(rnd); // Assuming an extension method on List<T> 

Shuffling is more efficient than sorting, aside from anything else. See my article on randomness for details about acquiring an appropriate Random instance though. There are lots of Fisher-Yates shuffle implementations available on Stack Overflow.

like image 168
Jon Skeet Avatar answered Oct 01 '22 13:10

Jon Skeet