数据访问层 - 模块化和可重用性

时间:2011-04-15 22:52:56

标签: c# .net design-patterns

我真的很陌生,我正在努力为我找到最好的数据访问层架构。 我的解决方案中有3层:

  1. 表示层 - ASP.net应用程序
  2. 业务逻辑层 - c#对象和逻辑
  3. 数据访问层 - 调用存储过程的函数。
  4. 我想要替换数据访问层。

    如果我使用实体框架或NHibernate,那么为什么以后我能够在不更改业务逻辑层的情况下替换该数据访问层呢? 在实体框架中使用接口,还是NHibernate?

3 个答案:

答案 0 :(得分:2)

设计一个界面,列出您在DAL中使用的所有关键方法。然后只通过接口引用DAL类。这将通过将层彼此分离来实现模块化。

每当您需要交换所述DAL时,您只需要插入一个实现所述接口的新DAL。其余的代码将不会更改。

解决问题的方法之一。

答案 1 :(得分:1)

为了保留业务层,您还必须保留模型。因为业务与模型的关系非常紧密。

您可以更改的是将模型映射到数据库的图层。

NHibernateEntity Framework 4.1都允许我们称之为POCO对象。 POCO objetcs是纯CLR对象,不引用任何特定于持久性的类。即:它不包含任何属性或基类,或者将此类耦合到程序集的方法调用。在使用NHibernate时,您可以使用XML文件或使用Fluent NHibernate的流畅方法将这些POCO类映射到数据库。在EF4.1中,您只能使用流利的方法。

您必须关注的一件事是使用stored procedures。这本质上是对持久层替换的妥协。 EF4.1 POCO方法目前不支持存储过程。 NHibernate可能会这样,但我不确定。

修改

正如Matthew Cox所说。当然,在涉及DAL类时需要接口。因为CRUD操作在持久层之间会有所不同。这些接口将允许持久性替换。

示例:

public class IPersonDAL {
    IList<Person> GetPeople();
    void InsertPerson(Person person);
    ...
}

答案 2 :(得分:1)

特别是nHibernate(3.0+)和EF支持LINQ,因此您的代码创建了一个简单的IRepository接口,它接受Expression<Func<TItemType,bool>>并避免拥有具有GetPersonByID,getPersonByName等的存储库。虽然这可能会妨碍您交换ORM我认为你不会使用不支持LINQ的ORM。

这个界面看起来像这样(这是 NOT 一个完整的实现!这是只是一个演示,真正的界面需要更好的再融资!这只是我现在嘲笑的东西!这可能还需要实现IDisposable等。):

interface IRepository<TPersistant>
{
      void Save(TPersistant item);
      void Delete(TPersistant item);

      TPersistant Find(Expression<Func<TPersistant,bool>> predicate); 
      // maybe findOne or findMany

      // maybe something like this
      IQueryable<TPersistant> Query();
      /* Other stuff like updating, transactions, commiting, etc.*/
}
但是,我想提一下人们在抽象DAL时忽略的一些事情。 这个o / c完全是我的意见

虽然抽象可以帮助你在将来“交换”DAL,但是如果你从中获得任何东西,我会很努力,除了创建符合“最佳实践”的软件以及“人们说你应该做什么”的软件,以及另一方面用脚射击自己。

当您完全抽象DAL时,您可能会丢失其他ORM特定功能,这些功能实际上使一个ORM比另一个更好,甚至是为了抽象而进行的未来性能优化。 i / e nHibernate中的未来查询(这是一个巨大的特性),如果你将它抽象出去,你基本上就会失败。您可能还会丢失延迟初始化优化(选择N + 1个问题),因为您无法使用Fetch(nHibernate)或Include(EF)。甚至像枚举支持这样的小东西(我相信EF STILL不支持)。

我还想补充一点,很多开发人员为了未来的变化而创建抽象,而实际上这些变化几乎从未发生过。

所以虽然我说不抽象DAL,因为有很多很多的优点,比如单元测试,解耦等等(尽管你总是可以创建一个可以帮助进行单元测试的耦合到dal存储库),如果值得付出实际使nhibernate / EF优于某些功能的一些功能付出代价,那么它应该被认真考虑。其他