Подтвердить что ты не робот

Где вы помещаете SQL-выражения в свои проекты С#?

Я, скорее всего, буду нести ответственность за перенос приложения vb6 на С#. Это приложение представляет собой приложение Windows, которое взаимодействует с db доступа. Доступ к данным инкапсулирован в основные бизнес-объекты. Один класс для одной таблицы в основном. Существующие бизнес-объекты vb6 читают и записывают в БД через DAO. Несколько раз я писал DAL и ORM, но все они нацелены только на SQL Server. Этому нужно будет настроить целевой доступ и сервер sql. В предыдущих проектах я бы поместил строки SQL в частные части бизнес-объекта и, возможно, переместил избыточный код sql, как соединение, создав команду, в общий базовый класс, чтобы уменьшить код.

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

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

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

Спасибо!

4b9b3361

Ответ 1

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

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

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 у вас есть хорошее чистое разделение между вашим программным кодом С# и операторами SQL.

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

Марк

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

  • Подкласс для каждого поддерживаемого сервера базы данных с помощью метода init, который присваивает переменным элемента базового класса

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

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

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

Ответ 5

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

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

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

        //etc....
}

Ответ 6

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

Ответ 7

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

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

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

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

Ответ 8

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

Ответ 9

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

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

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