Сохранение агностики базы данных приложения (ADO.NET и инкапсулирующая логика БД)

Мы делаем довольно серьезное приложение, которое должно оставаться агностическим для БД, который клиент хочет использовать. Сначала мы планируем поддерживать MySQL, Oracle и SQL Server. Таблицы и представления просты, как и запросы (без реального фантастического SQL), поэтому вопрос:

  • Используйте собственные драйверы DB (MySQLDbConnection и т.д.) и инкапсулируйте логику выполнения запросов и результатов обработки или
  • Использовать общий OleDbConnection

Очевидно, что вариант 2 не требует накладных расходов, но я предполагаю, что производительность не такая же высокая, как у собственного доступа?

Ответ 1

Примечание.. Этот ответ имеет значение, если вы решили использовать базовую функциональность ADO.NET 2 вместо ORM (например, Entity Framework или NHibernate) или LINQ to SQL.

Предположим, что у вас есть строка соединения, определенная в app.config:

<connectionStrings>
    <add name="SomeConnection"
         providerName="System.Data.SqlClient"
         connectionString="..." />
</connectionStrings>

Обратите внимание на наличие атрибута providerName и его значение. Вы также можете добавить значение для другого поставщика БД, например. System.Data.SQLite.

(Обратите внимание, что нестандартные поставщики, т.е. те, которые не находятся в .NET Framework по умолчанию, должны быть зарегистрированы сначала, либо в app.config или на клиентском компьютере machine.config.)

Теперь вы можете работать с указанной базой данных полностью агентом-агентом, следующим образом:

using System.Configuration;  // for ConfigurationManager
using System.Data;           // for all interface types
using System.Data.Common;    // for DbProviderFactories

var cs = ConfigurationManager.ConnectionStrings["SomeConnection"];
//                                              ^^^^^^^^^^^^^^^^

var factory = DbProviderFactories.GetFactory(cs.ProviderName);
//                                           ^^^^^^^^^^^^^^^

using (IDbConnection connection = factory.CreateConnection())
{
    connection.ConnectionString = cs.ConnectionString;
    //                            ^^^^^^^^^^^^^^^^^^^
    connection.Open();
    try
    {
        using (IDbCommand command = connection.CreateCommand())
        {
            ...  // do something with the database
        }
    }
    finally
    {
        connection.Close();
    }
}

Обратите внимание, как этот код работает только с типами интерфейсов. Единственное место, где вы указываете конкретного поставщика БД, - это значение атрибута providerName в файле app.config. (Я отметил все места, в которых с ^^^ s выбрана настройка из app.config).


Дальнейшее чтение:

Ответ 2

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

Ответ 3

Вам не нужно OleDbConnection для доступа к неспецифическим провайдерам ADO.NET. Просто используйте DbConnection et. и др. Для получения дополнительной информации см. DbProviderFactories в MSDN.

Ответ 4

Включив Oracle в этот список, вы гарантировали, что ничего не будет просто.

  • Oracle использует другой префиксный символ (двоеточие) для параметров, по сравнению с SQL Server, который использует символ "at".
  • Oracle использует один тип данных (число) для long, int, short, boolean, float и decimal; ваш код должен быть уверен, что вы правильно их сопоставляете.
  • Вы должны параметризовать значения даты и времени Oracle; если вы попытаетесь использовать строки для дат в ваших операторах SQL, вы сойдете с ума из-за формата даты Oracle. (Oracle использует трехзначную аббревиатуру месяца, формат 01-JAN-2010.)
  • Основные функции SQL для обработки нулей могут быть разными, в частности, для коллаборации нулей. ( "NVL" по сравнению с "COALESCE" ). Oracle значительно отбирает зарезервированные слова.
  • В Oracle нет поддержки столбцов идентификаторов. Методы обхода включают последовательности, триггеры и требуют транзакций только для получения значения идентификации из новой строки.

Другими словами, ваше приложение не может быть DB-агностиком. Если вы не используете ORM, вам определенно захочется создать слой доступа к данным, который скрывает все эти вещи от остальной части приложения.

Голос опыта здесь. Просто говорю'. Для общей схемы в SQL Server и Oracle нам нужно было построить большую часть инфраструктуры ORM, избегая при этом аспектов, которые могут ухудшить производительность. Интересно, но нетривиально, определенно!

Ответ 5

LINQ - высокоприоритетный .NET ORM, отчасти потому, что вы можете использовать его и хранимые процедуры. Проблема в том, что это только SQL Server, но люди работают над тем, чтобы обеспечить аналогичную функциональность для Oracle и MySQL.

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

Ответ 6

Нет никаких оснований избегать наиболее общих интерфейсов с самой широкой поддержкой - OleDb и даже ODBC, если вам удобно с ними. Все, что выходит за рамки этого, уменьшает количество продуктов/языков/платформ/инструментов/разработчиков, с которыми вы можете работать. Будучи самым близким к SQL-металу, поставщик не собирается вводить много неэффективности - безусловно, меньше, чем более эзотерические варианты. Они были вокруг долго, долго, чтобы выжать любые проблемы.

Если вы собираетесь добавить слой абстракции (ваш собственный или чужой), то это должно решаться на основе достоинств абстракций, введенных в вашем конкретном контексте, а не только для того, чтобы иметь слой абстракции (который просто больше поддержки, если нет намеренной выгоды.)

Как вы можете видеть, каждый пробег меняется.:) Но в целом, я думаю, что проще.

Ответ 7

Почему бы не использовать Microsoft Шаблоны и методы Enterprise Library Блок приложений доступа к данным. Там минимальные накладные расходы и поставщики коммутации являются быстрыми.

Цитата:

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

Ответ 8

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

Таким образом, вы получаете развязку при использовании DAL, но преимущества улучшения производительности или специфические для поставщика конструкции в DAL.