Случайная строка от Linq до Sql

Если ваш вопрос: «Какой код я бы написал для работы в качестве фильтра в приложениях Reactive и Non-Reactive Spring, ответ будет невозможным. Вы можете написать простой класс / компонент, который будет использоваться из хотя и WebFilter или Filter.

110
задан Cœur 27 December 2016 в 15:20
поделиться

3 ответа

Можно сделать это в базе данных, при помощи поддельного UDF; в частичном классе добавьте метод к контексту данных:

partial class MyDataContext {
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}

Тогда всего order by ctx.Random(); это сделает случайное упорядочивание в любезности SQL Server NEWID(). т.е.

var cust = (from row in ctx.Customers
           where row.IsActive // your filter
           orderby ctx.Random()
           select row).FirstOrDefault();

Примечание, что это только подходит для small-to-mid-size таблиц; для огромных таблиц это окажет влияние производительности в сервере, и будет более эффективно найти количество строк (Count), затем выбрать ту наугад (Skip/First).

<час>

для подхода количества:

var qry = from row in ctx.Customers
          where row.IsActive
          select row;

int count = qry.Count(); // 1st round-trip
int index = new Random().Next(count);

Customer cust = qry.Skip(index).FirstOrDefault(); // 2nd round-trip
167
ответ дан Armstrongest 24 November 2019 в 03:11
поделиться

РЕДАКТИРОВАНИЕ: я только что заметил, что это - LINQ к SQL, не LINQ к Объектам. Используйте код Marc, чтобы заставить базу данных делать это для Вас. Я оставил этот ответ здесь как потенциальное интересное место для LINQ к Объектам.

Странно достаточно, Вы не должны на самом деле получать количество. Действительно, однако, необходимо выбрать каждый элемент, если Вы не получаете количество.

то, Что можно сделать, является содержанием идея "текущего" значения и текущего количества. Когда Вы выбираете следующее значение, берете случайное число и заменяете "ток" "новым" с вероятностью 1/n, где n является количеством.

Поэтому при чтении первого значения Вы всегда делаете это "текущим" значением. При чтении второго значения Вы могли бы делать это текущим значением (вероятность 1/2). При чтении третьего значения Вы могли бы делать это текущим значением (вероятность 1/3) и т.д., Когда у Вас закончились данные, текущее значение является случайным из всего те, Вы читаете с универсальной вероятностью.

Для применения этого с условием просто проигнорируйте что-либо, что не удовлетворяет условию. Самый легкий способ сделать, который должен только рассмотреть последовательность "соответствия" для начала, путем применения оператора Where сначала.

Вот быстрая реализация. Я думаю , это хорошо...

public static T RandomElement<T>(this IEnumerable<T> source,
                                 Random rng)
{
    T current = default(T);
    int count = 0;
    foreach (T element in source)
    {
        count++;
        if (rng.Next(count) == 0)
        {
            current = element;
        }            
    }
    if (count == 0)
    {
        throw new InvalidOperationException("Sequence was empty");
    }
    return current;
}
31
ответ дан Jon Skeet 24 November 2019 в 03:11
поделиться

Один из способов добиться эффективного - добавить столбец к вашим данным Перемешать , заполненный случайное целое число (при создании каждой записи).

Частичный запрос для доступа к таблице в случайном порядке ...

Random random = new Random();
int seed = random.Next();
result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);

Это выполняет операцию XOR в базе данных и упорядочивает результаты этого XOR.

Преимущества: -

  1. Эффективность: SQL обрабатывает заказ, нет необходимости забирать весь таблица
  2. Повторяемый: (подходит для тестирование) - можно использовать тот же случайный семя для генерации того же случайного order

Это подход, используемый моей системой домашней автоматизации для рандомизации списков воспроизведения. Он выбирает новое начальное число каждый день, обеспечивая постоянный порядок в течение дня (позволяя легко приостанавливать / возобновлять воспроизведение), но каждый новый день свежим взглядом на каждый список воспроизведения.

19
ответ дан 24 November 2019 в 03:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: