Где вы помещаете операторы SQL в свои проекты c#?

Я, вероятно, буду нести ответственность за перенос приложения vb6 на c#. Это приложение представляет собой приложение windows, которое взаимодействует с БД access. Доступ к данным инкапсулируется в базовые бизнес-объекты. Один класс для одной таблицы в основном. Существующие бизнес-объекты vb6 считывают и записывают в БД через DAO. Я писал DALs и ORMs несколько раз раньше, но все они были нацелены только на SQL Server. Этот должен быть нацелен на access и sql server. В предыдущих проектах я бы разместил строки SQL в частных частях бизнес-объекта и, возможно, переместить избыточный код sql, например, подключение, создание команды, в общий базовый класс для уменьшения кода.

на этот раз я думаю о записи строк SQL в a .файл настроек или другой текстовый файл типа ключ/значение. Затем я бы написал утилиту sql для редактирования этого файла и позволил мне запускать и тестировать параметризованные запросы. Эти запросы будут ссылаться по имени в бизнес-объекте вместо внедрения sql в код.

Я знаю, что стандартный подход-создать DAL для каждой целевой базы данных и иметь состояние конфигурации, которое DAL использовать. Я действительно не хочу создавать два класса DAL для каждой базы данных. Похоже, было бы меньше кода, если бы я просто ссылался на правильный запрос keyname и имел правильный тип соединения.

Итак, вы, ребята, делаете такие вещи? Как бы вы подошли к этой проблеме? Что работает лучше всего для тебя?

спасибо!

9 ответов


Ну, тут много вариантов - так что это действительно зависит от того, что ваши самые насущные потребности :-)

один из подходов может заключаться в создании операторов SQL в виде текстовых файлов внутри вашего решения VS и пометить их как "встроенный ресурс" в "действие сборки". Таким образом, SQL включается в результирующую сборку и может быть извлечен из нее во время выполнения с помощью ResourceManifestStream .NET framework:

private string LoadSQLStatement(string statementName)
{
    string sqlStatement = string.Empty;

    string namespacePart = "ConsoleApplication1";
    string resourceName = namespacePart + "." + statementName;

    using(Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
    {
        if (stm != null)
        {
            sqlStatement = new StreamReader(stm).ReadToEnd();
        }
    }

    return sqlStatement;
}

вам нужно заменить "ConsoleApplication1" на фактическое пространство имен, в котором находятся файлы инструкций sql. Вы должны ссылаться на них с помощью полного имени. Затем вы можете загрузить инструкцию SQL с помощью этой строки:

string mySQLStatement = LoadSQLStatement("MySQLStatement.sql");

это, однако, делает запросы скорее "статическими", например, вы не можете настроить и изменить их во время выполнения - они запекаются прямо в скомпилированные двоичные биты. Но, с другой стороны, в VS у вас есть хорошее чистое разделение между вашим программным кодом C# и SQL заявления.

Если вам нужно иметь возможность настраивать и изменять их во время выполнения, я бы поместил их в одну таблицу SQL, которая содержит, например, ключевое слово и фактический SQL-запрос в виде полей. Затем вы можете получить их по мере необходимости и выполнить их. Поскольку они находятся в таблице базы данных, вы также можете изменять, исправлять, изменять их по желанию - даже во время выполнения - без необходимости повторного развертывания всего приложения.

Марк


когда мне это действительно нужно, я помещаю запросы в индивидуальный *.файлы sql, затем включите их в ресурсы.resx файл. В нем есть раздел "файлы", который позволяет включать встроенные файлы ресурсов.

после этого, я могу использовать созданные ресурсы.MyQuery свойство, которое гарантирует, что ресурс существует и спасает меня от написания пользовательского метода загрузки ресурсов.


LINQ to DataSet звучит как способ пойти для вас.

Если вы не использовали .NET 3.5 до / LINQ, то вы находитесь в для лечения. LINQ избавит вас от написания необработанного sql в строковых литералах и предоставит вам более логичный способ создания запросов.

в любом случае, проверьте эту ссылку для использования LINQ в базах данных Access -http://msdn.microsoft.com/en-us/library/bb386977.aspx


Я скажу, куда я никогда не положу его, что-то, что я видел, сделано в каком-то коде, который я унаследовал. Это было на Java, но относится к любому языку

  • базовый класс, объявивший защищенные статические переменные-члены для операторов for SQL, inited в null, с методом get, который возвращает отдельные операторы SQL

  • подкласс для каждого поддерживаемого сервера баз данных с методом init, который назначает члену базового класса переменные

  • несколько классов DA, которые используют метод базового класса для извлечения операторов SQL

  • класс запуска приложения с ответственностью за создание правильного объекта подкласса и вызов его метода init

Я также не буду объяснять, почему я никогда этого не сделаю: -)


один из методов, который мы использовали, - это класс, который будет подключаться к БД и методам вызова процедур, а в параметре метода вы укажете имя процедуры. поэтому все SQL-код в процедуре. мы будем использовать перегрузки для разных типов возврата

class ConnectToSQL()
{
        //connectSql code (read from setting file i assume)

        XMLDataDocument runProcedure(string procedureName);
        int runProcedure(string procedureName);

        //etc....
}

Если бы мне пришлось создать приложение для SQL и Access, я бы использовал некоторый IDAL-интерфейс, DALCommon с общей реализацией функциональности и отдельными DALSql и DALAccess, унаследованными от DALCommon, с некоторыми конкретными вещами, такими как исключения, обработка транзакций, безопасность и т. д.
Я использовал имена хранимых процедур или запросы в файлах ресурсов.


иногда, как и в пользовательских приложениях отчетов, вам действительно нужно принять несоответствие импеданса и придать особое значение SQL. В этих случаях я рекомендую следующее: для каждого модуля, содержащего строки SQL, создайте один статический класс "SQL", чтобы удерживать их все. Некоторые из строк SQL, вероятно, потребуют параметров, поэтому будьте последовательны и поместите каждую строку за свой собственный статический метод.

Я делаю это только для случайного пользовательского приложения отчетности, но это всегда отлично работает и чувствует себя освежающим и освобождающим. И довольно приятно вернуться через несколько месяцев, чтобы сделать улучшение, и найти весь SQL, ожидающий вас в одном SQL.cs файл. Просто прочитав этот файл, все возвращается, и часто это единственный файл, который нужно изменить.

Я не вижу необходимости в этих случаях скрывать SQL в ресурсах или в другом месте. Когда SQL важен, тогда это важно. Интересно, что все больше и больше разработчиков теперь свободно смешивание SQL с C#, в том числе я считаю этот сайт, потому что, по сути, это то, что LINQ.

наконец, как всегда, убедитесь, что вы не подвержены атакам SQL-инъекций. Особенно если используется пользовательский ввод, убедитесь, что вы используете какую-то параметризацию и не используете конкатенацию строк.


встраивание решений, показанных выше , может не работать, если SQL-запрос имеет причину "где", но для того же запроса следующий запуск требует PropertyID='113', поскольку PropertyID считывается.


рад, что вы спросили! Поместите свой sql в QueryFirst .в SQL шаблон.

он автоматически компилируется в ваше приложение как встроенный ресурс, но вам все равно. Вы просто пишете его в реальном окне sql, подключенном к вашей БД, с проверкой синтаксиса и intellisense для таблиц и столбцов, а затем используете его через сгенерированный Execute() методы, с intellisense для ваших входных данных и результатов.

отказ от ответственности: я написал QueryFirst.