【问题标题】:Trying to understand how to abstract my data access layer试图了解如何抽象我的数据访问层
【发布时间】:2011-04-11 21:54:58
【问题描述】:

我正在编写一个应用程序,用于对文件进行编目,并为这些文件赋予元数据。相册程序可以很好地与我正在尝试做的事情进行比较。

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    我自己编写了三个不同的 DAL/ORMS,支持 SQL Server、Mysql、postgresql 和 sqlite。但现在我改用休眠模式。完全按照自己的意愿得到一切是不值得的。

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

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

    分页是每个数据库都有自己的实现的另一件事。 Sql 服务器更像是一个 hack。

    【讨论】:

    • 是的,我也得出了这个结论。我当然不想重新发明轮子。我一直在研究 SubSonic,现在我正在考虑 NHibernate。我遇到的一个问题是我想要选择允许“类表继承”(martinfowler.com/eaaCatalog/classTableInheritance.html) 的任何解决方案。从我看到的情况来看,亚音速总是希望将一个类的所有属性(继承与否)存储在该类的相应表中。 NHibernate 可以将继承关系反映到单独的表中吗?
    • 我想是的。 nhibernate 是 .net 中最成熟的 ORM 之一。自 2003 年从 Javas Hibernate 移植以来,它就一直存在。看看这个帖子(不知道有没有帮助):ayende.com/Blog/archive/2009/04/10/…
    • 如果您不想使用 XML 文件将表映射到类,也可以查看 fluent nhibernate。 wiki.fluentnhibernate.org/Fluent_mapping#Subclasses
    • 关于亚音速:如果我没记错的话,您的表必须与您的类(列/属性名称)相同。这违背了 DAL 的目的。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-01
      • 2013-12-05
      • 2011-02-19
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多