Сегодня столкнулся с проблемой рандомной выборки из базы данных, используя Linq To Sql. Например, ситуация такая: при переходе на страницу товара, вам также необходимо выгрузить несколько товаров из той же категории, но чтобы они выгружались рандомно (в произвольной последовательности).
При использовании T-SQL наш запрос должен выглядеть примерно так:
select * from products order by newid()
Итак, будем считать, что для уникального ключа в таблице товаров вы используете UniqueIdentifier (в C# это Guid), то при использовании наш запрос в Linq преобразуется в:
using (EcommerceDataContext dbContext = new EcommerceDataContext()) { var items = dbContext.Products.OrderBy(products => Guid.NewGuid()); }
Однако, вы увидите, что записи будут выгружаться только в той последовательности, в которой они были загружены. Для того, чтобы всё работало, необходимо связать функцию C# Guid.NewGuid() с функцией SQL newid(). Для этого необходимо следующее:
- щелкаем правой кнопкой по вашему dbml-файлу и переходим в режим кода;
- вы увидите примерно следующее:
using System; using System.Data.Linq.Mapping; partial class EcommerceDataContext { }
- теперь необходимо вставить заветный код-связку:
[Function(Name = "NEWID", IsComposable = true)] public Guid NewId() { return Guid.NewGuid(); }
- Name - название функции SQL Server;
- IsComposable - true, если мы вызываем функцию (например, хранимые процедуры и пр.).
using (EcommerceDataContext dbContext = new EcommerceDataContext()) { var items = dbContext.Products.OrderBy(products => dbContext.NewId()).Take(5); }
Число 5 в функции Take() означает, что необходимо взять 5 рандомных записей. Вуаля! Если что-то не работает - пишите. :)
3 комментария:
Это грязный читинг!
Но за идею спасибо, хитрое решение! :)
Во-первых, не читинг, а идея! Во-вторых, не грязная, а нормальная, чтобы её использовать, САША! :)
Спасибо, дружище! Помог!
Отправить комментарий