Linq Orderby random ThreadSafe for use in ASP.NET
Solution 1:
One way to achieve efficiently is to add a column to your data Shuffle
that is populated with a random int (as each record is created).
The query to access the table then becomes ...
Random random = new Random();
int seed = random.Next();
result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);
This does an XOR operation in the database and orders by the results of that XOR.
Advantages:-
- Efficient: SQL handles the ordering, no need to fetch the whole table
- Repeatable: (good for testing) - can use the same random seed to generate the same random order
- Works on most (all?) Entity Framework supported databases
This is the approach used by my home automation system to randomize playlists. It picks a new seed each day giving a consistent order during the day (allowing easy pause / resume capabilities) but a fresh look at each playlist each new day.
Solution 2:
You can do this in T-Sql as described here. I don't think you can do it in linq without loading the whole result set into memory and then throwing most of it away, which you do not want to do.
Solution 3:
Random random = new Random();
return _repositoryKeyWord.FindAll(x => x.Category.Id == idCAtegory)
.OrderBy(x => r.Next())
.Take(50).ToList();
Solution 4:
Probably best to write your own extension method to do it.
public static class Extensions
{
static readonly Random random = new Random();
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
{
return Shuffle(items, random);
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items, Random random)
{
// Un-optimized algorithm taken from
// http://en.wikipedia.org/wiki/Knuth_shuffle#The_modern_algorithm
List<T> list = new List<T>(items);
for (int i = list.Count - 1; i >= 1; i--)
{
int j = random.Next(0, i);
T temp = list[i];
list[i] = list[j];
list[j] = temp;
}
return list;
}
}