В зависимости от базы данных, это может работать:
var banners = Database.Banners.Where(b => b.IsPublish.Value &&
b.Category.Value == (int) CategoryBanner.Banner &&
b.PeriodShowCountAlready < b.PeriodShowCount ||
b.ShowNext < DateTime.Now);
Тогда просто пропустить случайное количество баннеров ...
var skip = new Random().Next(banners.Count() - 1);
var banner = banners.Skip(skip).FirstOrDefault();
Как указывает Амар, этот подход является менее оптимальным, поскольку он вызывает две поездки в банк данных. Из моего собственного опыта профилирования, поездка туда и обратно на другой сервер чаще всего стоит намного больше, чем выполнение простого оператора SQL.
Итак, какие у вас варианты?
Извлеките весь набор и выберите случайный баннер локально. Это не оптимально, потому что набор может быть очень большим. Если вы знаете, что набор будет небольшим (менее 1000 записей без двоичных полей [например, изображение баннера] или менее 10 тыс. Вообще должны быть незначительными)
Задайте в базе данных, сколько объектов есть в первую очередь, и затем спросите базу данных для n: th объекта. Это плохо, потому что это вызывает две поездки.
Сделать базу данных сделать все, что внутренне выходит из комфорта вашего ORM и записывает хранимую процедуру вручную. С этой целью вы используете newid() [на сервере sql] в качестве порядка по параметру, и все быстро и полезно, но вы должны делать это на сервере, а не в своем приложении C#.
http://stackoverflow.com/questions/648196/random-row-from-linq-to-sql –
В '.Снять (1) .FirstOrDefault()' '.Снять (1)' часть полностью избыточна. – spender