Пытаясь понять, как абстрагировать мой уровень доступа к данным - PullRequest
1 голос
/ 14 сентября 2010

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

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

Например, я создал интерфейс IFileSystemAdaptor, которыйиспользуется для чтения и записи файлов и связанных метафайлов (миниатюр и вложений) в файловую систему.Фактические реализации IFileSystemAdaptor определяют, где хранятся файлы и в какой структуре.

public interface IFileSystemAdaptor
{
    void WriteFileData(string fileName, Stream data);
    Stream ReadFileData(string filename);
    void DeleteFileData(string filename);
    void ClearAllData();
    void WriteMetaFileData(string filename, string path, Stream data);
    Stream ReadMetaFileData(string filename, string path, Stream data);
    void DeleteMetaFileData(string filename, string path);
    void ClearMetaFilesData(string filename);
}

Так что теперь я пытаюсь сделать нечто подобное с подключением к базе данных.У меня есть довольно сложная структура классов , которую я хочу читать и записывать в базу данных и из нее.Я хотел бы иметь возможность иметь реализации, которые подключаются к базе данных SQL Server, и другую реализацию, которая использует базу данных без серверов, такую ​​как SQL Lite.

Как я могу абстрагировать слой доступа к данным между моими классами ибаза данных таким образом, который будет поддерживать несколько типов баз данных?Кроме того, как я могу позволить отражать отношения наследования в моих классах в базе данных?Я бы предпочел формат базы данных в соответствии с шаблоном " наследование таблиц классов " (см. Один из моих предыдущих вопросов ).

Ответы [ 2 ]

3 голосов
/ 14 сентября 2010

Зачем изобретать велосипед? Используйте nhibernate

Все уже сделано для вас. Вы можете сохранить все свои модели и легко переключить ядро ​​базы данных.

Я сам написал три разных DAL / ORMS с поддержкой SQL Server, Mysql, postgresql и sqlite. Но сейчас я переключаюсь на nhibernate вместо этого. Это не стоит хлопот, чтобы получить все именно так, как вы этого хотите.

Если вы все еще хотите сделать это самостоятельно, вы должны помнить, что большинство баз данных добавили свои собственные «умные» функции в SQL, с которыми вам приходится работать. Вы должны прочитать о стандарте SQL92 и придерживаться этих типов данных.

При вставке строк вам нужно по-разному обрабатывать получение первичного ключа для большинства механизмов баз данных (некоторые механизмы используют генераторы для получения значения PK ДО вставки строки, в то время как другие имеют функции, которые вы используете для получения значения PK ПОСЛЕ вставки)

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

1 голос
/ 14 сентября 2010

Я только обращаюсь к тому, как абстрагировать уровень доступа к данным в той степени, в которой он поддерживает несколько поставщиков баз данных.Вы можете использовать класс DbProviderFactory из .NET Framework, который использует шаблон Factory для предоставления абстракции базовых компонентов базы данных.Вам необходимо настроить значение строки подключения и имя поставщика (например, System.Data.SqlClient для SQL Server).С помощью имени провайдера вы можете создать конкретный класс фабрики, а затем с помощью строки соединения вы можете создавать объекты соединений, из которых вы можете создавать объекты команд и т. Д. Это позволит вам кодировать уровень доступа к данным независимо от основного поставщика базы данных.,Имейте в виду, что параметризованный запрос, разработанный для SQL Server (например), будет использовать параметры с именем, например @parametername, тогда как другие механизмы баз данных будут использовать другой формат для указания параметров.Таким образом, хотя тип объектов базы данных будет корректным при использовании фабрики, текст запросов необходимо будет тщательно рассмотреть, если вы намерены поддерживать разные механизмы базы данных.

...