Куда ставить sql при использовании dapper?

Я использую dapper для проекта mvc3 на работе, и мне это нравится. Однако как вы должны распределять приложение при использовании dapper? В настоящее время у меня просто есть весь мой sql, набитый непосредственно в контроллере (slap), но я думал о создании класса со статическими строками. Так что я мог бы сделать

var reports = Dapper.Query<Report>(conn, MySql.ReportsRunningQuery)

Как вы храните свой sql при использовании dapper?


person Christian Wattengård    schedule 13.05.2011    source источник
comment
предположительно, это класс со статическими строками, а не перечисление?   -  person Marc Gravell    schedule 13.05.2011
comment
Что ж. да. Плохие утренние мысли... (отредактировано)   -  person Christian Wattengård    schedule 13.05.2011


Ответы (3)


Я бы сказал поместите sql там, где вы бы разместили эквивалентный запрос LINQ, или sql для DataContext.ExecuteQuery. Что касается того, где это... ну, это зависит от вас и от того, насколько сильное разделение вы хотите.

Однако лично я не вижу смысла скрывать SQL в отдельном классе от вызова Query<T> — вы хотите видеть их в контексте, чтобы можно было легко проверить данные (и, конечно, параметры). Вы также можете создавать запрос (все еще параметризованный) на месте. Но для обычного статического запроса я бы оставил TSQL как литерал рядом с кодом, если только у меня нет веской причины для его абстрагирования, т.е.

var reports = conn.Query<Report>(@"
select x.blah, y.blah
from x (snip)
where x.ParentId = @parentId and y.Region = @region", new {parentId, region});

(обратите внимание на использование альтернативного метода расширения выше)

ИМО, суть вышеизложенного в том, что крайне маловероятно, что вы когда-либо будете повторно использовать этот запрос из любого другого места — логика вместо этого будет помещен в метод, и этот метод будет вызываться из нескольких мест. Таким образом, единственная другая причина, по которой вы можете скрыть запрос за центральной оболочкой, заключается в том, что вам нужно поддерживать разных поставщиков баз данных (с разными диалектами SQL). И это реже, чем люди разбирают.

person Marc Gravell    schedule 13.05.2011
comment
Об использовании этого метода расширения... Как мне заставить это работать? Потому что мой нет :/ - person Christian Wattengård; 13.05.2011
comment
@Christian - просто убедитесь, что у вас есть директива using Dapper; - person Marc Gravell; 13.05.2011
comment
Спасибо. Но поместив весь sql в контроллер, разве вы не сделаете толстый контроллер? И в зависимости от того, кого вы спросите, разве это не Плохая вещь? - person Christian Wattengård; 13.05.2011
comment
@Christian Я намеренно ничего не сказал о контроллере. Если вы выбираете доступ к данным в своем контроллере, то спор о том, где живет TSQL, является спорным вопросом - доступ к данным все еще существует. Полнота зависит от того, что она делает, а не от количества строк кода. - person Marc Gravell; 13.05.2011
comment
да. Спасибо. Я думаю, что это, вероятно, неправильное приложение для изучения MVC и многоуровневой архитектуры. (Это веб-интерфейс для устаревшей БД) - person Christian Wattengård; 13.05.2011
comment
Кристиан, ознакомьтесь с шаблоном репозитория. Вы можете получить доступ к данным в классе репозитория, абстрагированном от ваших контроллеров. В идеале ваша модель будет в отдельном проекте. Старайтесь содержать свои контроллеры в чистоте и общайтесь с моделью через репозиторий, чтобы вы могли максимально абстрагироваться от базы данных. Таким образом, вы можете легко имитировать и подделывать данные, если вам нужно запустить модульные тесты или даже изменить механизм БД в будущем. - person Diego; 19.05.2011
comment
(Не поймите меня неправильно. Я уважаю работу Марка над множеством Dapper, но...) TSQL выполняется в другом месте, чем LINQ/C#. Так же, как Javascript выполняется в другом месте, кроме C#. Вам нравится смешивать Javascript с C#? Возможно нет. То же самое должно относиться к TSQL. Вот почему я предпочитаю использовать хранимые процедуры, в которых находится вся логика SQL, и максимально автоматизировать вызовы к ним. Используя T4, именно поэтому я получаю intellisense, ошибки времени компиляции и снижаю ошибки человеческого фактора. C# должен быть C#, TSQL должен быть TSQL, Javascript должен быть Javascript, а HTML должен быть HTML. Вещи должны быть разделены по причине. - person Robert Koritnik; 21.05.2011
comment
@Robert - это зависит от вас, но это ортогонально. Dapper может вызывать хранимые процедуры (включая выходные параметры и т. д.). Дело в том, чтобы просто обеспечить эффективную материализацию ваших записей. Я не говорю вам, как или где разместить логику данных, именно поэтому я избегал обсуждения контроллера выше. Я работал в средах SP и в средах без SP. У обоих есть плюсы и минусы. Но опять же: это ортогонально до щегольства. Dapper будет совершенно счастлив звонить SPROC - person Marc Gravell; 21.05.2011
comment
@Robert - одним из очень убедительных преимуществ SP-free является простота развертывания; и гибкий SQL без необходимости генерировать SQL внутри SQL (для использования с sp_executesql), но любой выбор может быть допустимым - person Marc Gravell; 21.05.2011
comment
@Марк: я полностью с тобой согласен. Один побочный вопрос: насколько вероятно, что Dapper будет расширен полезными функциями для PetaPoco (такими как автоматическое обнаружение разделения и автоматические ссылки)? Я спрашиваю, потому что этот проект был в основном написан для ускорения SO и преуспел в этом. Насколько вероятно, что он будет расширен по причинам сообщества (не как форк, а как основной продукт)? - person Robert Koritnik; 21.05.2011
comment
@ Роберт, нет проблем; рад рассмотреть все, что зарегистрировано как предложение функции. Мы добавили ряд функций по предложению сообщества — некоторые из них мы теперь используем внутри, некоторые — нет. - person Marc Gravell; 21.05.2011

Использование файла ресурсов действительно полезно для нас. Мы создаем файлы .sql в папке с вызовом /Sql и перетаскиваем их в раздел «Файлы» нашего объекта SqlResource. Раздел «Строки» файла ресурсов действительно чист и удобен для небольших фрагментов sql (например, функций, которые мы можем запрашивать).

Итак, наш sql выглядит так:

var reports = conn.Query<Report>(SqlResource.Blahs_get, new {parentId, region});

Это держит репозитории в чистоте. И есть дополнительные преимущества наличия всего вашего sql в файле ресурсов, поскольку вы можете перебирать записи и потенциально запрашивать базу данных с помощью PARSEONLY, чтобы убедиться, что если объекты базы данных изменятся, ваши запросы прервутся (обратите внимание, что это в основном, но не 100% надежность).

Итак, в заключение, для нас файлы ресурсов сохраняют чистоту, но, по мнению Марка Гравелла, они не предназначены для повторного использования в производственном коде... каждый оператор sql должен использоваться только в одной точке вашего приложения.

person BlackjacketMack    schedule 29.09.2013

Хотя этот вопрос сейчас значительно устарел, я хотел бы дополнительно предложить внешнее хранилище SQL. Visual Studio (по крайней мере, 2015+) имеет подсветку синтаксиса, а также небольшой отладчик и менеджер соединений для файлов *.sql. Файлы могут быть помечены как встроенные ресурсы и полностью содержаться в сборке, но отдельно от вашего кода. Вы начнете ненавидеть бесцветный SQL, встроенный в строки без проверки синтаксиса.

Я использовал этот шаблон во всех своих последних проектах, и в сочетании с ORM, например Dapper, интерфейс между C# и SQL становится минимальным. У меня есть проект с открытым исходным кодом, расширяющий Dapper, доступный на GitHub, который может предоставить примеры, а также Пакет NuGet. Он также включает механизм замены строк, вдохновленный усами, который полезен для создания шаблонов ваших сценариев, чтобы сделать их повторно используемыми, или для вставки условий динамической фильтрации.

person Null511    schedule 01.12.2017
comment
Я не помню, было ли это в этом конкретном проекте. Но в итоге я использовал .SQL-файлы и T4-генератор, который генерировал статический класс строковых констант. Таким образом, я мог получить запрос SQL.Filename из любого места в моем коде. - person Christian Wattengård; 01.12.2017
comment
Ах, это умный подход; и обеспечивает интеграцию с Dapper (или вообще с чем-либо) без каких-либо модификаций. Единственная часть, к которой я беспристрастен, - это полагаться на внешний инструмент в процессе разработки, но я полагаю, что добавление его в событие сборки в основном автоматизирует этот процесс. Спасибо за продолжение и дополнительное предложение. - person Null511; 01.12.2017
comment
Поскольку я пользователь Visual Studio, обработка T4 интегрирована в IDE. Я бы, наверное, просто проверил полученные .cs-файлы. Таким образом, в этом случае не потребуется никаких дополнительных шагов сборки. - person Christian Wattengård; 08.12.2017