Web应用程序中的NHibernate查询策略

mbu*_*bue 6 c# nhibernate asp.net-mvc asp.net-mvc-3

在Web应用程序场景中,通常有两个关于数据检索的要求:1.所有查询都需要可选地进行分页2.用户需要很多"过滤"查询(例如,按姓名和邮件和年龄搜索人员)3.对某些客户端网格隐含的查询进行排序

当然还有组合案例:已筛选的分页查询:)

这些要求可能导致数据层中的很多存储库方法,每个方法都有很多参数.是否有任何常见的模式为此过程提供更动态的行为(例如,根据域类属性自动生成的查询)?

我知道存储库方法应该干净且定义明确.但是目前,每当我向MVC视图或某个可排序的分页表添加一些过滤形式时,我都想编写很多样板代码.

其他开发人员如何处理这些要求?

先感谢您

Bro*_*ski 7

存储IQueryable的存储库,通用存储库和存储库是一个激烈的辩论.

底线是一个通用或暴露的存储库IQueryable根本不是一个真正的存储库,它只是数据层的抽象.

现在这不是一件坏事,但不要把它称为存储库,称之为它.数据层抽象允许您快速向UI中插入内容,您可以在其中读取和写入实体,而不会将数据层框架泄漏到UI中.你当然可以注入ISession并完成它.

public interface IRepository<T> {}

public class NHibernateRepository<T> : IRepository<T>
{
    private ISession session;

    public NHibernateRepository(ISession session)
    {
        this.session = session;
    }

    T Get(object id) { return session.GetById<T>(id)); }

    IQueryable<T> Query { get { return session.Query<T>(); }
}

new NHibernateRepository<Customer>(session).Query().Where(customer => customer.Name == Fred);
Run Code Online (Sandbox Code Playgroud)

但是,如果您想捕获一些可重用的逻辑并在服务或UI与数据层之间提供明确的契约,那么存储库就是这样做的.您可以定义明确的方法,说明检索的内容和方式.此外,对于存储库,您只想公开聚合根,这些是所有其他数据挂起的根实体,这些可能是CustomerSupplier.你不会试图直接到达一个地址,你会加载一个客户,然后查询他的地址.您可以根据供应商提供的内容加载供应商列表,但不会通过"ItemsRepository"进行.我的例子可能不是最好的,但它们会给你一个想法.

public class CustomerRepository
{
    public Customer GetCustomerWithName(string name);
}

public class SupplierRepository
{
    public IEnumerable<Supplier> GetSuppliersWhoStockItem(string itemName)
}
Run Code Online (Sandbox Code Playgroud)

最后,如果你喜欢冒险,你可能想看看CQRS,这里要概述的主题很多,但有很多例子.

第一个是更快实现,第二个为您提供更清晰的可重用代码,第三个为您提供UI层之间的分离,但需要更多的基础工作.这取决于你需要和想要什么,应该按顺序处理.