Каков наилучший (и самый быстрый) способ получить случайную строку с помощью Linq to SQL, когда у меня есть условие, например, какое-то поле должно быть истинным?
c#
.net
linq-to-sql
Жюльен Пулен
источник
источник
Ответы:
Вы можете сделать это в базе данных, используя поддельный UDF; в частичном классе добавьте метод в контекст данных:
Тогда просто
order by ctx.Random()
; это сделает случайный заказ на SQL-сервереNEWID()
. т.е.Обратите внимание, что это подходит только для столов малого и среднего размера; для огромных таблиц это повлияет на производительность сервера, и будет более эффективно найти количество строк (
Count
), а затем выбрать одну случайным образом (Skip/First
).для счетного подхода:
источник
Еще один пример для Entity Framework:
Это не работает с LINQ to SQL.
OrderBy
Просто при падении.источник
РЕДАКТИРОВАТЬ: Я только что заметил, что это LINQ to SQL, а не LINQ to Objects. Используйте код Марка, чтобы база данных сделала это за вас. Я оставил этот ответ здесь как потенциальный интерес для LINQ to Objects.
Как ни странно, на самом деле вам не нужно подсчитывать. Однако вам нужно получить каждый элемент, если вы не получите счетчик.
Что вы можете сделать, так это сохранить представление о «текущем» значении и текущем счетчике. Когда вы выбираете следующее значение, возьмите случайное число и замените «текущее» на «новое» с вероятностью 1 / n, где n - количество.
Поэтому, когда вы читаете первое значение, вы всегда делаете его «текущим» значением. Когда вы читаете второе значение, вы можете сделать это текущее значение (вероятность 1/2). Когда вы читаете третье значение, вы можете сделать это текущее значение (вероятность 1/3) и т. Д. Когда у вас закончились данные, текущее значение является случайным из всех считанных вами значений с равномерной вероятностью.
Чтобы применить это с условием, просто игнорируйте все, что не соответствует условию. Самый простой способ сделать это - рассмотреть для начала только «совпадающую» последовательность, применив сначала предложение Where.
Вот быстрая реализация. Я думаю , что это нормально ...
источник
current
будет всегда быть установлен на первый элемент. На второй итерации происходит изменение на 50%, которое будет установлено для второго элемента. На третьей итерации с вероятностью 33% будет установлен третий элемент. Добавление оператора break будет означать, что вы всегда будете выходить после прочтения первого элемента, что делает его совсем не случайным.Один из способов добиться эффективного - добавить к вашим данным столбец,
Shuffle
который заполняется случайным int (по мере создания каждой записи).Частичный запрос для доступа к таблице в случайном порядке ...
Это выполняет операцию XOR в базе данных и упорядочивает результаты этого XOR.
Преимущества: -
Это подход, используемый моей системой домашней автоматизации для рандомизации списков воспроизведения. Он выбирает новое начальное число каждый день, давая постоянный порядок в течение дня (позволяя легко приостанавливать / возобновлять воспроизведение), но каждый день свежим взглядом на каждый список воспроизведения.
источник
result = result.OrderBy(s => s.Shuffle ^ seed);
(т.е. нет необходимости реализовывать XOR с помощью операторов ~, & и |).если вы хотите получить, например,
var count = 16
случайные строки из таблицы, вы можете написатьздесь я использовал EF, а таблица - это Dbset
источник
Если целью получения случайных строк является выборка, я очень кратко рассказал здесь о хорошем подходе Ларсона и др., Исследовательской группы Microsoft, где они разработали структуру выборки для Sql Server с использованием материализованных представлений. Также есть ссылка на сам документ.
источник
Объяснение: При вставке guid (который является случайным) порядок с помощью orderby будет случайным.
источник
Пришел сюда, задаваясь вопросом, как получить несколько случайных страниц из небольшого их количества, чтобы каждый пользователь получил несколько разных случайных 3 страниц.
Это мое последнее решение: работа с запросами с LINQ по списку страниц в Sharepoint 2010. Это в Visual Basic, извините: p
Вероятно, следует провести профилирование, прежде чем запрашивать большое количество результатов, но это идеально подходит для моей цели
источник
У меня есть случайный запрос функции к
DataTable
s:источник
В приведенном ниже примере вызывается источник для получения счетчика, а затем применяется выражение пропуска к источнику с числом от 0 до n. Второй метод применяет порядок, используя случайный объект (который упорядочит все в памяти) и выбирает число, переданное в вызов метода.
источник
Я использую этот метод для получения случайных новостей, и он отлично работает;)
источник
Использование LINQ to SQL в LINQPad, поскольку операторы C # выглядят так
Сгенерированный SQL
источник
Если вы используете LINQPad , переключитесь в программный режим C # и сделайте следующее:
источник
Выбрать случайные 2 строки
источник
Чтобы добавить к раствору Марка Гравелла. Если вы не работаете с самим классом datacontext (потому что вы каким-то образом проксируете его, например, чтобы подделать текст данных в целях тестирования), вы не можете напрямую использовать определенный UDF: он не будет скомпилирован в SQL, потому что вы не используете его в подкласс или частичный класс вашего реального класса контекста данных.
Обходной путь для этой проблемы - создать функцию Randomize в вашем прокси-сервере, передав ей запрос, который вы хотите рандомизировать:
Вот как вы бы использовали это в своем коде:
Чтобы завершить, вот как это реализовать в поддельном тексте данных (который используется в объектах памяти):
источник