2010-09-13 3 views
1

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

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

Например, я создал интерфейс, 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); 
} 

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

Как я могу отделить уровень доступа к данным между моими классами и базой данных таким образом, чтобы поддерживать несколько типов баз данных? Также как я могу позволить отношениям наследования в моих классах отражаться в базе данных? Я бы предпочел формат базы данных, следующий за шаблоном «class table inheritance» (см. Один из моих previous questions).

ответ

1

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

3

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

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

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

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

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

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

+0

Да, я тоже прихожу к этому выводу. Я, конечно, не хочу изобретать велосипед. Я изучал SubSonic, и теперь я рассматриваю NHibernate. Одна из проблем, которые есть у меня, - это то, что я хотел бы, чтобы любое решение, которое я выбрал, позволял «Наследование класса» (http://martinfowler.com/eaaCatalog/classTableInheritance.html). Из того, что я вижу, субзвук всегда хочет сохранить все свойства класса (унаследованного или нет) в соответствующей таблице для этого класса. Может ли NHibernate отображать отношения наследования в отдельные таблицы? –

+0

Думаю, что так. nhibernate является одним из самых зрелых ORM для .net. Он существует с 2003 года, когда он был перенесен из Javas Hibernate. Взгляните на этот пост (не знаю, если это поможет): http://ayende.com/Blog/archive/2009/04/10/nhibernate-mapping-ndash-inheritance.aspx – jgauffin

+0

Вы также можете свободно смотреть на nhibernate, если вы не хотите использовать XML-файлы для сопоставления таблиц с вашими классами. http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses – jgauffin

Смежные вопросы