C# 如何使用NHibernate组织数据库层

C# 如何使用NHibernate组织数据库层,c#,linq,nhibernate,architecture,C#,Linq,Nhibernate,Architecture,为了关注这里的问题,我们可以说我有一个数据库层和一个应用程序层。因此,为了让应用程序访问数据库,我必须通过数据库层(当然) 现在的问题是,我想使用LINQ编写查询。我可以走两条不同的路。一种方法是在数据库层中创建大约300个单独的函数,并从应用程序中调用它们(例如GetAllUsers()) 或者[B]数据库层可以或多或少地提供一个数据库上下文,然后我可以从应用程序层运行LINQ查询(DBContext.GetAll()。其中(x=>x…) 我认为[B]路径会更吸引人,或者至少不会那么烦人,因为

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

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

或者[B]数据库层可以或多或少地提供一个数据库上下文,然后我可以从应用程序层运行LINQ查询(
DBContext.GetAll()。其中(x=>x…

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


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

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

事实上,非常容易做到。您的数据层只需发布今天的标准:IQueryable

本机NHibernate LINQ提供商将为您执行以下操作:

var query = session.Query<TEntity>()
var query=session.query()
实际上是返回一个var查询,该查询是
IQueryable

因此数据层contaract(接口IDao…)可能是这样的(下面是实现)

公共虚拟IQueryable GetQueryable()
{
var会话=。。。。
返回sesion.query();
}
在这种情况下,没有上层会注意到它正在与NHibernate一起工作。事实上,在某些情况下,它可能会收到不同的
IQueryable
提供者的结果

扩展:

我还想在Ayende block post上附加一个(我甚至会说是有争议的)链接:

引用:

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

虽然Ayende通常不是(至少在撰写本文时是这样的:数据、业务、服务层的爱好者……上面的logcic类似于:

将查询(IQueryable)传递到上层。如果需要,应用一些自定义过滤器(更多地限制结果),但让客户端应用程序(用户)使用它来查询API,使用LINQ(B)的解决方案当然更可取(与解决方案A中描述的300个单独函数相比)

事实上,非常容易做到。您的数据层只需发布今天的标准:IQueryable

本机NHibernate LINQ提供商将为您执行以下操作:

var query = session.Query<TEntity>()
var query=session.query()
实际上是返回一个var查询,该查询是
IQueryable

因此数据层contaract(接口IDao…)可能是这样的(下面是实现)

公共虚拟IQueryable GetQueryable()
{
var会话=。。。。
返回sesion.query();
}
在这种情况下,没有上层会注意到它正在与NHibernate一起工作。事实上,在某些情况下,它可能会收到不同的
IQueryable
提供者的结果

扩展:

我还想在Ayende block post上附加一个(我甚至会说是有争议的)链接:

引用:

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

虽然Ayende通常不是(至少在撰写本文时是这样的:数据、业务、服务层的爱好者……上面的logcic类似于:


将查询(IQueryable)传递到上层。如果需要,应用一些自定义筛选器(进一步限制结果),但让客户端应用程序(用户)要使用它,要查询您的API选项A并提及您不需要创建300个函数的内容,您需要根据应用程序的需要创建尽可能多的函数。有些函数可以获得一个减少函数数量的标准


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

选项A提到不需要创建300个函数的内容,您需要创建多达300个函数应用程序需求所需。某些函数可以获得减少函数数量的标准


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

这意味着应用程序将始终需要实现IQueryable和相同持久性实体的东西现在,为什么应用程序的其余部分应该告诉持久性如何工作(构建queris等)?@Rippo我喜欢你的评论,我真的喜欢。关于“架构”的问题只是个人问题,不像“为什么我得到1+N选择”那么容易。不要为此而奋斗