Question

I’m using NHibernate for data access, but accessing it through a façade layer. This layer consists of interfaces for the repositories, plus an IUnitOfWork interface which corresponds to the ISession object.

In order that retrieved entities are managed correctly, repositories are passed an IUnitOfWork in their constructor and the IUnitOfWork is used for the loading.

The IUnitOfWork contains a property called All, which retrieves all entities of the class as an IQueryable (for later filtering). Thus, a repository method to retrieve all entities created this year might look like the following:

NB: this is not the complete code for these interfaces and classes! Only the code relevant to my question.

IUnitOfWork interface:

IQueryable<T> GetList<T>();

UnitOfWork concrete class:

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

IFooRepository interface

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

FooRepository concrete class

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);}
}

I would like to add functionality to specify fetch strategies so that related entities can be eagerly loaded. So let’s say Foo has a property corresponding to another entity, Bar:

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

The mapping file specifies that Bar is lazy-loaded, but in my ThisYearsFoos repository property I would like to specify that Bar should be eagerly loaded to avoid N+1 selects.

In Linq to NHibernate we can specify eager fetching using the Expand() extension method. However, this extension method belongs to the NHibernateQueryable type, whereas the IUnitOfWork interface’s GetList method only knows about IQueryable.

Clearly I don’t want the IUnitOfWork interface to know about INHibernateQueryable since it is supposed to not know about NHibernate.

Using the design I have specified above, is there a way to do this that I haven’t been able to think of? Or is my design in need of a rethink?

Thanks

David

Was it helpful?

Solution

Upgrade to NHibernate 3.x. The new method that corresponds to Expand (Fetch) operates on IQueryable.

OTHER TIPS

You are saying some conflicting things: - You don't want to expose interface - You want to use the use that interface

That is impossible. You have to rethink your design. You use the term unit of work for a different thing than most people do. Most people would expect a unit of work interface to have the methods Commit and RollBack, but not some IQueryable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top