Мы подаем довольно серьезную заявку, которая должна остаться агностиком к DB, который клиент хочет использовать. Первоначально мы планируем поддержку MySQL, Oracle & SQL Server. Таблицы и представления просты, как запросы (никакой реальный необычный SQL), поэтому вопрос:
Опция 2 Obviously не включает издержек, но меня предполагающий, что производительность не является столь же большой как с собственным доступом?
Включив Oracle в этот список, вы гарантировали, что все будет просто.
Другими словами, ваше приложение не может быть независимым от БД. Если вы не используете ORM, вам обязательно нужно создать уровень доступа к данным, который скрывает все эти вещи от остальной части приложения.
Голос опыта здесь. Просто говорю'. Для общей схемы для SQL Server и Oracle нам пришлось построить большую часть инфраструктуры ORM, избегая при этом аспектов, которые могут снизить производительность. Интересно, но однозначно нетривиально!
ИМХО, использование ORM - хорошее дизайнерское решение для приложения, не зависящего от базы данных. Переключение базы данных может быть таким же простым, как изменение настройки конфигурации и строки подключения.
Нет никаких веских причин избегать наиболее общих интерфейсов с самой широкой поддержкой - OleDb и даже ODBC, если вам удобно с ними работать. Все, что выходит за эти рамки, уменьшает набор продуктов/языков/платформ/инструментов/разработчиков, с которыми вы можете работать. Находясь ближе всего к металлу SQL, этот производитель не внесет много неэффективности - уж точно меньше, чем более эзотерические варианты. Они существуют уже очень, очень давно, чтобы устранить все проблемы.
Если вы собираетесь добавить уровень абстракции (свой или чужой), то это должно решаться на основе достоинств абстракций, вводимых в вашем конкретном контексте, а не просто для того, чтобы иметь уровень абстракции (который является просто дополнительной поддержкой, если нет намеренной выгоды).
Как видите, у каждого свой пробег. :) Но в целом, я думаю, что проще - значит лучше.
LINQ - это высоко оцененный .NET ORM, отчасти потому, что вы можете использовать его и хранимые процедуры. Проблема в том, что это только SQL Server, но люди работают над обеспечением аналогичной функциональности для Oracle и MySQL.
Для оптимизации баз данных и запросов мне не нравится идея использования ORM. Типы данных, функции и общий синтаксис не очень переносимы в SQL. Наиболее эффективным средством взаимодействия с каждой базой данных будет адаптация модели и запросов к каждой из них, но это требует специальных знаний, времени и денег. Если необходимо, сосредоточьтесь на одном поставщике баз данных с настройкой кода для поддержки замены поставщика и добавьте поддержку других баз данных по мере необходимости.
Примечание: Этот ответ актуален, если вы решите использовать базовую функциональность 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
взяты с ^^^
s.)
Общее кодирование с помощью ADO Базовые классы и фабрики .NET 2.0 :
похоже на мой ответ, но более подробно.
Центр разработки управляемых поставщиков и наборов данных ADO.NET :
включает, среди прочего, индекс доступных поставщиков баз данных ADO.NET.
Почему бы не использовать блок приложения доступа к данным Microsoft Patterns & Practices Enterprise Library . Накладные расходы минимальны, а переключение провайдера - несложно.
Цитата:
Блок приложения доступа к данным пользуется преимуществами этих классов и предоставляет модель, которая дополнительно поддерживает инкапсуляция базы данных тип - специфические особенности, такие как обнаружение и тип параметра конверсии. Из-за этого, приложения можно портировать с одного тип базы данных на другой без изменение клиентского кода.
Вам не требуется OleDbConnection
для доступа к неспецифическим поставщикам ADO.NET. Просто используйте DbConnection
et. al. См. DbProviderFactories
в MSDN для получения дополнительной информации.
Вы всегда можете сделать часть базы данных приложения независимой, если большая часть приложения будет использовать DAL в качестве связки интерфейсов. Тогда сам DAL обеспечит конкретную реализацию целевой базы данных.
Таким образом, вы получаете развязку при использовании DAL, но при этом получаете выгоду от улучшений производительности или построений, специфичных для поставщика, внутри DAL.