【问题标题】:How to organize database layer using NHibernate如何使用 NHibernate 组织数据库层
【发布时间】:2014-01-31 17:30:13
【问题描述】:

这里集中讨论这个问题,我们可以说我有一个数据库层和一个应用程序层。因此,为了让应用程序能够访问数据库,我必须通过数据库层(当然)。

现在我想使用 LINQ 编写查询。我可以在这里走两条不同的路。 [A] 的一种方法是在 DBLayer 中创建大约 300 个单独的函数,并从应用程序中调用它们(例如,GetAllUsers())。

[B] DBLayer 或多或少只提供一个 DBContext,然后我可以从应用层 (DBContext.GetAll<Users>().Where(x => x...) 运行 LINQ 查询。

我认为 [B] 路径会更吸引人,或者至少不那么烦人,因为它不会被小函数填满。但是你会说什么呢?


但是 [B] 路径的问题在于,如果我可以避免它,我不想在应用程序中引用 NHibernate,但我似乎无法访问 NHibernate 函数的 LINQ没有引用它。有什么好的解决办法吗?

【问题讨论】:

    标签: c# linq nhibernate architecture


    【解决方案1】:

    选项 A 提到您不需要创建 300 个函数,您需要根据应用程序的需要创建尽可能多的函数。并且一些函数可以获得一个减少函数数量的标准。

    最重要的是所有这些函数都将返回应用程序对象而不是持久性对象,从而使应用程序的其余部分与持久性分离。当然,business/ui 对象也不应该知道 NH。

    【讨论】:

      【解决方案2】:

      LINQ (B) 的解决方案当然更可取(与解决方案 A 中描述的 300 个单独的函数相比)

      事实上很容易做到。您的数据层将发布今天的标准:IQueryable

      本机 NHibernate LINQ 提供程序将为您做到这一点:

      var query = session.Query<TEntity>()
      

      实际上是返回一个 var 查询,即 IQueryable&lt;TEntity&gt;

      所以Data layer contaract(interface IDao...)可能是这样(下面是实现)

      public virtual IQueryable<MyEntity> GetQueryable()
      {
          var session = ....
          return sesion.query<MyEntity>();
      }
      

      在这种情况下,任何上层都不会注意到它正在使用 NHibernate。实际上在某些情况下可能会收到不同 IQueryable 提供者的结果

      扩展:

      我还想附加一个 (我什至会说有争议) 链接到 Ayende 块帖子:The DAL should go all the way to UI

      引用:

      ...我目前的做法完全不同。我定义了查询,其中包含查询的实际业务逻辑,但我将该查询向前传递到我的应用程序的更高级别。可以对查询进行任何附加处理(投影、分页、排序等)。通过这种方式,我的查询对修改关闭,对扩展开放,因为它们可以被更高级别的代码进一步操作......

      虽然 Ayende 一般不是(至少在撰写本文时:Don’t castrate your architecture 数据、业务、服务层的粉丝......上面的逻辑是相似的:

      将查询 (IQueryable) 传递给上层。如果需要,应用一些自定义过滤器(更多地限制结果),但让客户端应用程序(用户)使用它,查询您的 API

      【讨论】:

      • 这意味着应用程序将始终需要实现 IQueryable 和与 NH 相同的 Persistence 实体的东西。现在,WHY 应用程序的其余部分应该告诉 Persistence 如何完成它的工作(构建查询等)?
      • @Rippo 我喜欢你的评论,我真的很喜欢。关于“架构”的问题只是个人问题,不像“为什么我得到 1 + N 个选择”那么简单;)。不为这种方法而战。我的经验是:你拥有的独立数据层越灵活,返回 POCO (stackoverflow.com/a/13632872/1679310) 的上层越灵活。老实说,直到现在我才搞砸了! ;) ;) 我的会话运行良好...而且我确实关心数据层上的数据、业务层上的规则以及客户端上的查询...无论如何,关于架构的答案并不容易,对吧? ;)
      • 不,这是一个最好的话题,可以讨论一品脱啤酒:)
      • 其实没什么好争论的。想要将应用程序与所有持久性分离 -> 使用适当的存储库模式。只想从应用程序中的任何地方以 oop 方式访问数据库 -> 直接使用 ORM。但是直接使用 ORM(或泄漏的 IQueryable - 不要打扰)应该知道您的应用程序与持久性非常紧密耦合。对于很多应用程序,您不需要更多。对于您选择的任何解决方案,您都需要了解权衡取舍。
      • 听起来你已经下定决心了,我的 debate 将谈论权衡,所以是的 a topic best left to debate over a pint of beer ;)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2020-04-28
      • 2016-09-23
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多