Сохранение независимости базы данных приложения (ADO.NET против инкапсулирующей логики БД) - PullRequest
13 голосов
/ 20 июня 2010

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

  1. Используйте собственные драйверы БД (MySQLDbConnection и т. Д.) И инкапсулируйте логику выполнения запросов и результатов обработки или
  2. Использовать универсальный OleDbConnection

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

Ответы [ 8 ]

11 голосов
/ 20 июня 2010

Примечание: Этот ответ актуален, если вы решите использовать базовые функции 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.(Я отметил все места, где берется настройка от app.config с ^^^ с.)


Дополнительная информация:

7 голосов
/ 20 июня 2010

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

4 голосов
/ 20 июня 2010

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

3 голосов
/ 21 июня 2010

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

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

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

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

2 голосов
/ 20 июня 2010

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

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

0 голосов
/ 24 июня 2010

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

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

0 голосов
/ 21 июня 2010

Почему бы не использовать Microsoft Patterns & Practices Корпоративная библиотека Блок приложения доступа к данным. Там минимальные накладные расходы и переключение провайдеров совсем несложно.

Цитата:

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

0 голосов
/ 21 июня 2010

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

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

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

...