Как вернуть совпадающие объекты в случайном порядке?
Просто чтобы прояснить это вещи Entity Framework и LINQ to Entities
(воздушный кодекс)
IEnumerable<MyEntity> results = from en in context.MyEntity
where en.type == myTypeVar
orderby ?????
select en;
Спасибо
Редактировать:
Я попытался добавить это в контекст:
public Guid Random()
{
return new Guid();
}
И используя этот запрос:
IEnumerable<MyEntity> results = from en in context.MyEntity
where en.type == myTypeVar
orderby context.Random()
select en;
Но я получил эту ошибку:
System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Guid Random()' method, and this method cannot be translated into a store expression..
Изменить (Текущий код):
IEnumerable<MyEntity> results = (from en in context.MyEntity
where en.type == myTypeVar
orderby context.Random()
select en).AsEnumerable();
Простым решением было бы создать массив (или List<T>
) и затем рандомизировать его индексы.
РЕДАКТИРОВАТЬ:
static IEnumerable<T> Randomize<T>(this IEnumerable<T> source) {
var array = source.ToArray();
// randomize indexes (several approaches are possible)
return array;
}
РЕДАКТИРОВАТЬ: Лично я нахожу ответ Джона Скита более элегантным:
var results = from ... in ... where ... orderby Guid.NewGuid() select ...
И, конечно же, вы можете взять генератор случайных чисел вместо Guid.NewGuid()
.
Простой способ сделать это - заказать с помощью Guid.NewGuid()
но тогда заказ происходит на стороне клиента. Возможно, вам удастся убедить EF сделать что-то случайное на стороне сервера, но это не обязательно просто - и делать это с помощью «порядка по случайному числу» явно не удается .
Чтобы упорядочение происходило на стороне .NET, а не в EF, вам нужно AsEnumerable
:
IEnumerable<MyEntity> results = context.MyEntity
.Where(en => en.type == myTypeVar)
.AsEnumerable()
.OrderBy(en => context.Random());
Было бы лучше получить неупорядоченную версию в списке, а затем перемешать ее.
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>
Перемешивание более эффективно, чем сортировка, помимо всего прочего. См. Мою статью о случайности для получения подробной информации о приобретении соответствующего экземпляра Random
. В переполнении стека доступно множество реализаций Фишера-Йейтса.