试图了解如何抽象我的数据访问层

时间:2010-09-13 22:10:36

标签: c# .net orm data-access-layer

我正在编写一个用于编目文件的应用程序,并将这些文件归类为元数据。相册程序与我正在尝试的相比是一个很好的比较。

我正在尝试抽象我的程序和存储文件的文件系统之间的接口,以及存储文件元数据的数据库。这是为了允许模拟和单元测试。另外,我希望能够创建我的工具的多个实现,这些实现可以利用不同的数据库格式和/或文件系统结构。

例如,我创建了一个接口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之一)。

2 个答案:

答案 0 :(得分:3)

为什么重新发明轮子?使用nhibernate

一切都已经为你完成了。您可以保留所有模型,并且可以轻松切换数据库引擎。

我自己写了三个不同的DAL / ORMS,支持SQL Server,Mysql,postgresql和sqlite。但是现在我转而使用nhibernate。按照你的意愿完全获取所有东西是不值得的。

如果您仍想自己动手,则必须记住,大多数数据库都已将自己的“智能”功能添加到您必须处理的SQL中。您需要阅读SQL92标准并坚持使用这些数据类型。

插入行时,您需要对大多数数据库引擎执行不同的处理主键的修复(某些引擎使用生成器在插入行之前获取PK值,而其他引擎则使用用于在插入之后检索PK值的函数)

分页是另一个每个数据库都有自己的实现的东西。 Sql服务器更像是一个黑客。

答案 1 :(得分:1)

我只讨论如何将数据访问层抽象到支持多个数据库提供程序的程度。您可以使用.NET框架中的DbProviderFactory类,它使用Factory模式提供底层数据库组件的抽象。您需要配置连接字符串值和提供程序名称(我认为,对于SQL Server,如System.Data.SqlClient)。使用提供程序名称,您可以创建一个具体的工厂类,然后使用连接字符串创建连接对象,您可以从中创建命令对象等。这将允许您独立于底层数据库提供程序编写数据访问层的代码。请注意,为SQL Server设计的参数化查询(例如)将使用名为@parametername的参数,而其他数据库引擎将使用不同的格式来指示参数。因此,虽然使用工厂数据库对象的类型是正确的,但如果您打算支持不同的数据库引擎,则需要仔细考虑查询的文本。