Question

When using Linq2Nibernate is better to make you Repository return a IQueryable?

My understanding is that if you use Linq to Nibernate the the query will not "fire" until you call .First() or Single() ect ect. So would it not be best to return IQueryable from all you Interfaces so you can build up\manipulate the expression tree before it fires?

My Repositories are called by a services and inherits from IServicie.

EDIT:

First I really appreciate all the answers. But I wan to add a little to the question. I am for this design. I don't fully understand the reservations around testing. As long as the process is tested at every point IE every filter point then I don't really see much of a difference.

addition:

Is there any point to Using Linq2Nibernate if your repository doesn't return IQuerrable?

Was it helpful?

Solution

Personally, I think not. The problem with exposing composable queries from your repository is that you can no longer fully unit test them - their behaviour (and success) is now at the mercy of the caller. For example, they might do .Where(x=>SomeUnmappedMethod(x)) (with no translation). I added more on this here.

If you have fixed methods that return (for example) IList<T> or T[], then you can be sure that if it works in the unit test, it should work for real (barring any configuration errors). It also means that you can profile the DAL in isolation and have reasonable confidence what SQL (etc) is going to be executed. You can't profile/optimise a DAL that changes based on the caller.

(based on my LINQ-to-SQL usage; not LINQ-to-NHibernate specifically)

OTHER TIPS

It depends on what's consuming your "Repository" (quotes because of ambiguity). I would say if something like your last layer (UI) is consuming your repository classes to NOT return an IQueryable. However if you have another layer between your UI layer and your Data Access layer I'd say yes, return IQueryable and have your middle layer handle the execution of the query.

EDIT

As for testing your Data Access Layer (DAL)/Repository I would say for the most part unless you have actual logic (if statements etc) there should be little to no testing. At that point you're testing the framework. My suggestion would to be put another layer between your accessing layer (UI) and the DAL like a BLL or something that handles the execution of the IQueryable queries. That way your repository can return queries and your BLL can handle executing them and maybe doing some logic which can then be tested.

I don't go with IQueryable, but I would explain why I do a bit differently:

  • Easier to mock the repository, to test the other code that uses it
  • Integration tests - most of the stuff that causes a query to be fired is in the repository, so I can do some really focused integration tests against it
  • Related to the first, easier to check the code is doing appropriate calls to the repository. This is because the calling code would pass the filters information to the repository method call, as opposed to applying them against the results.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top