БД Агностик ASP.Net? - PullRequest
       20

БД Агностик ASP.Net?

2 голосов
/ 18 декабря 2009

мы делаем приложение ASP.Net. Мы хотели бы, чтобы наше приложение было как минимум независимым от БД, наиболее заметным, чтобы быть совместимым как с SQL Server, так и с PostgreSQL. Каков наилучший способ сделать это? Каковы некоторые из распространенных ошибок? Также есть класс или что-то, что уже абстрагирует разницу между вещами типа SqlConnection и тем, что PostgreSQL использует для соединений?

(Мы хотим быть независимыми от БД, поэтому мы можем использовать PostgreSQL здесь (в разработке и позже на нашем собственном хостинге) из-за цены и позволить нашим клиентам, использующим хост, использовать Sql Server, если они того пожелают)

Ответы [ 8 ]

5 голосов
/ 18 декабря 2009

Все провайдеры ADO.Net расширяют базовые интерфейсы:

Таким образом, теоретически вы можете написать весь DAL (Data Access Layer) на основе абстрактных интерфейсов и использовать любого провайдера, включая сторонних, таких как MySQL. На практике ни одному смертному не удавалось справиться с этим трюком. С одной стороны, интерфейсы очень трудно программировать, и любое приложение, кроме демоверсии, быстро столкнется с несовместимостью диалектов SQL.

Более выполнимый подход состоит в том, чтобы рассчитать количество целевых пунктов назначения и разработать DAL. Entity Framework и шаблон репозитория, а также nHibernate и все такое, но ни одна из них не решает фундаментальные проблемы.

1 голос
/ 18 декабря 2009

Если вы просто хотите использовать ADO.NET напрямую, вы можете использовать DbProviderFactory для абстрагирования поставщика (SqlClient, OleDb и т. Д.), Который вы используете. Обычно вы используете это вместе с элементом конфигурации , с кодом примерно таким:

ConnectionStringSettings c = ConfigurationManager.ConnectionStrings[name];
DbProviderFactory factory = DbProviderFactories.GetFactory(c.ProviderName)
...
IDbConnection connection = _factory.CreateConnection();
connection.ConnectionString = c.ConnectionString;
...

В MSDN много информации.

Конечно, это не поможет вам с различиями в синтаксисе SQL между различными поставщиками - вам нужен подход с наименьшим общим знаменателем для работы с несколькими поставщиками. Это влияет на такие вещи, как синтаксис для параметров (например, префикс @ для SQL Server, позиционные параметры только для OleDb, ...).

1 голос
/ 18 декабря 2009

Вы можете использовать Entity Framework. Таким образом, у вас будет единая модель программирования для работы.

http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx

http://www.devart.com/dotconnect/postgresql/

0 голосов
/ 18 декабря 2009

На очень высоком уровне вы хотели бы использовать что-то, что абстрагирует вашу базу данных больше, чем просто классы SqlConnection, SqlCommand и Sql *. Поэтому, когда люди говорят об использовании ORM, они почти правы. ORM обеспечивают этот уровень абстракции для вас.

Но для абстрагирования SqlCommand и SqlConnection в пространстве имен System.Data есть интерфейсы. IDbConnection, IDbCommand и т. Д. Уже находятся внутри фреймворка, и вы можете кодировать их. Тогда проблема заключается в том, чтобы найти способ создания конкретных классов, и вы можете решить эту проблему с помощью контейнера IoC или шаблона поставщика.

0 голосов
/ 18 декабря 2009

Я бы порекомендовал использовать какой-нибудь шаблон репозитория.

Это не серебряная пуля, которая спасет вас от взлома для каждого варианта СУБД, но это путь, если вы хотите, чтобы он был обслуживаемым с самого начала, чего просто не предоставляют ORM.

http://blog.wekeroad.com/2008/04/07/asp-net-mvc-mvc-storefront-part-2

0 голосов
/ 18 декабря 2009

Лучшим решением для приложений, не зависящих от базы данных, обычно является ORM ( этот тег ). их достаточно для .NET - этот вопрос даст вам руководство по выбору.

Три самых популярных из них:

0 голосов
/ 18 декабря 2009

Entity Framework - это вариант, упомянутый Ширазом. Вы также можете рассмотреть другие решения ORM, такие как NHibernate .

0 голосов
/ 18 декабря 2009

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

public interface IMyProjectDataSource
{
    IEnumerable<string> GetUserNames();
    void AddUser(string userName);
}

public class SqlServerMyProjectDataSource : IMyProjectDataSource
{
    public SqlServerMyProjectDataSource(string connectionString)
    {
        //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class PostgreSqlMyProjectDataSource : IMyProjectDataSource
{

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {

    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

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

public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
    public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
    {
            //...
    }

    public IEnumerable<string> GetUserNames()
    {
        //...
    }

    public void AddUser(string userName)
    {
        //...
    }
}

Самое сложное - это решить, как его создать, особенно если вы планируете объединить в цепочку более одного. Для этого я обычно сохраняю его в своем Global.asax.cs как одиночный файл и создаю его из имени типа в файле .config. Вы можете использовать Type.GetType (), а затем Activator.CreateInstance (), чтобы сделать это, и большая часть цепочки, которую я имею, будет сделана независимо от того, какой источник данных в .config, поэтому мне не нужно беспокоиться о создании некоторых своего рода тип "конструктор" или сложный .config.

Надеюсь, это имеет смысл. Возможно, это не лучший вариант для всех ситуаций, но мне повезло с этим.

...