2

我使用 NHibernate 进行数据访问,但通过外观层访问它。该层由存储库的接口以及对应于 ISession 对象的 IUnitOfWork 接口组成。

为了正确管理检索到的实体,存储库在其构造函数中传递了一个 IUnitOfWork,并且 IUnitOfWork 用于加载。

IUnitOfWork 包含一个名为 All 的属性,它将类的所有实体作为 IQueryable 检索(用于以后过滤)。因此,检索今年创建的所有实体的存储库方法可能如下所示:

注意:这不是这些接口和类的完整代码!只有与我的问题相关的代码。

IUnitOfWork 接口:

IQueryable<T> GetList<T>();

UnitOfWork 具体类:

public IQueryable<T> GetList<T>()
{
  return _session.Linq<T>();
}

IFooRepository 接口

IQueryable<Foo> All { get; }
IEnumerable<Foo> ThisYearsFoos{ get; }

FooRepository 具体类

public IQueryable<Foo> All
{
  get { return _unitOfWork.GetList<Foo>(); }
}

public IEnumerable<Foo> ThisYearsFoos
{
  get { return All.Where(x => x.DateCreated > new DateTime(2010,1,1);}
}

我想添加功能来指定获取策略,以便可以急切地加载相关实体。假设 Foo 有一个对应于另一个实体 Bar 的属性:

public class Foo
{
    public Bar {get;set;}
}

映射文件指定 Bar 是延迟加载的,但在我的 ThisYearsFoos 存储库属性中,我想指定 Bar 应立即加载以避免 N+1 选择。

在 Linq to NHibernate 中,我们可以使用 Expand() 扩展方法指定预取。但是这个扩展方法属于NHibernateQueryable类型,而IUnitOfWork接口的GetList方法只知道IQueryable。

显然,我不希望 IUnitOfWork 接口知道 INHibernateQueryable,因为它应该不知道 NHibernate。

使用我上面指定的设计,有没有我想不到的方法来做到这一点?还是我的设计需要重新思考?

谢谢

大卫

4

2 回答 2

2

升级到 NHibernate 3.x。对应于 Expand ( Fetch) 的新方法对 IQueryable 进行操作。

于 2010-08-11T16:05:41.937 回答
0

您在说一些相互矛盾的事情:-您不想公开接口-您想使用该接口

那是不可能的。你必须重新考虑你的设计。您使用工作单元一词来表示与大多数人不同的事情。大多数人希望工作单元接口具有 Commit 和 RollBack 方法,但不是某些 IQueryable。

于 2010-08-11T14:50:05.040 回答