对与nHibernate分离问题感到困惑';分离与急加载

对与nHibernate分离问题感到困惑';分离与急加载,nhibernate,fluent-nhibernate,asp.net-mvc-3,Nhibernate,Fluent Nhibernate,Asp.net Mvc 3,我有一个使用Fluent NHibernate和ASP.NET MVC构建的应用程序。目前分为5个项目 网状物 ASP.NET MVC项目只包含HTML、CSS、控制器、特定于项目的验证器和模型绑定器,以及IoC容器Ninject 模型 Models项目包含域对象、IRepository、使用存储库的服务以及与数据库操作无关的辅助代码 坚持不懈 持久性项目包含Fluent nHibernate映射、ISessionFactory映射、存储库:IRepository实现等 持久性工具 这是一个辅助

我有一个使用Fluent NHibernate和ASP.NET MVC构建的应用程序。目前分为5个项目

网状物 ASP.NET MVC项目只包含HTML、CSS、控制器、特定于项目的验证器和模型绑定器,以及IoC容器
Ninject

模型 Models项目包含域对象、
IRepository
、使用存储库的服务以及与数据库操作无关的辅助代码

坚持不懈 持久性项目包含Fluent nHibernate映射、
ISessionFactory
映射、
存储库:IRepository
实现等

持久性工具 这是一个辅助项目,与我实际的最终产品几乎没有关系。这就是我放置测试数据库种子设定、用于快速设置的默认集合等内容的地方

试验 单元测试项目


我遇到的问题是
模型和
持久性之间的问题。有时我需要使用即时加载。在nHibernate中,我将使用
Query().Fetch(…)
来完成此操作。这可以正常工作,除了
Models.dll
没有nHibernate的概念。除了
System.dll
之外,它没有任何库的概念,并且是完全独立的

有没有一种特别的方法可以让我在不知道
NHibernate.Linq
的情况下,将即时加载功能添加到我的
IRepository
?我无法添加一个方法,该方法采用任何类型的lambda表达式,其中包含
Fetch
,因为我的持久性层在模型层中不存在。但是,
IRepository
存在于模型层,因为它用于服务对象,而服务对象也没有数据库的概念。他们只需访问适当的存储库。存储库不暴露于
Web
层,只暴露于适当的服务


有什么想法吗?

我想我了解你。。。因此,它基本上归结为如何实现存储库模式。您可以在fluent映射中设置即时加载,但不管怎样,听起来您只想在少数情况下进行即时加载,因此,NHibernate的内容仍然需要在当前设置中泄漏到您的模型项目中

回到整个存储库模式,我能想到的一个选择是使您的存储库稍微智能化

例如,在您的
模型中
项目有:

public interface IFooRepository : IRepository<Foo>
{
    IQueryable<Foo> GetAllFoosWithBars();
}
public class FooRepository : Repository<Foo>, IFooRepository
{
    public IQueryable<Foo> GetAllFoosWithBars()
    {
        return this.Session.Query<Foo>().Fetch(c => c.Bars);
        //I don't know the return type for .Fetch() off the top of
        //my head, so you might need a .AsQueryable() in there
    }
}

如果将IRepository定义为IQueryable,则可以在存储库本身上使用LINQ。例如:

public interface IRepository<T> : IQueryable<T>
{
}

public class Repository<T> : IRepository<T>
{
    public Repository(ISession session)
    {
        query = session.Query<T>();
    }

    public Type ElementType
    {
        get { return query.ElementType; }
    }
    public Expression Expression
    {
        get { return query.Expression; }
    }
    public IQueryProvider Provider
    {
        get { return query.Provider; }
    }

    IQueryable<T> query;
}
我遇到的问题是模型之间的持久性。那里 在某些时候,我需要使用即时加载。在nHibernate,我 将使用Query().Fetch(…)执行此操作。这样就行了, 除了Models.dll没有nHibernate的概念。它没有概念 除System.dll之外的任何库都是完全独立的


在我看来,一个能从NH中获益最多的图书馆没有使用它。只有Web和持久性使用NH,但正是模型使用了隐藏在低特性IRepository后面的NH的抽象版本。我建议您允许NH进入模型并利用ISession,它实际上是一个增强的全功能存储库。

我不明白为什么您不能在
持久化
项目中保留急切加载的知识。。。为什么
Models
project需要了解它?我在问
how
如何将它保存在持久性项目中。我无法通过我的
IRepository
传递一个了解NHibernate
Fetch
方法的查询,但是
IRepository
必须在
模型
项目中。我担心这将是唯一的解决方案。因此,基本上我需要在需要的地方扩展我的存储库,而不是保持简单的存储库结构。
IRepository<Foo> repo = new Repository<Foo>();
Foo foo = repo.FirstOrDefault(f => f.Bar == "bar");