Работа с БД через Linq2Sql
Столкнулся тут на работе с задачей - из огромного представления надо по запросу получить либо вообще все, либо несколько сотен первых записей с предварительной сортировкой. Казалось бы, что могло пойти не так?
Не, ну реально! Есть некий "репозиторий", который ломится в базу, и у "репа" есть методы Get(), Get(Func
Пишу код типа:
1 | var allEntities1 = EntityRep.Get(); |
И следом
1 | var allEntities2 = EntityRep.Get(o => o.Name.Contains("SomeString").OrderByDescending(o => o.Id).Take(100)); |
И ситуация такова, что первый запрос выполняется, к примеру, минуту. Сколько ж должен выполняться второй? Угу, есть ненулевая вероятность, что тоже минуту.
Проблема в том, что Linq2Sql далеко не всегда формирует нормальные запросы (ну или у меня так репозитории построены). Так что в некоторых случаях становится значительно проще и дешевле формировать строкой SQL-запрос, и его уже передавать репозиторию на выполнение:
1 2 | string sqlQuery = "Select * from some_entities where name like '%" + "SomeString" + "%'"; var res = rep.Get(sqlQuery); |
Внутри репа, соответственно, как вариант:
1 2 3 4 | public IQueryable<SomeEntity> Get(string sqlQuery) { return DbConnect.ExecuteQuery<SomeEntity>(sqlQuery).AsQueryable(); } |
В результате в сервак БД отправляется именно тот запрос, который был сформирован вручную. Скорость - примерно как внутри MS SQL Studio / dbForge / Dbeavier / etc.
Из минусов - не дай боже кто-то или что-то поменяет структуру таблицы/представления, откуда подсасываются данные.