I am using EF4 with code first and have a repository for persistence and a service layer that interacts with it. I have a service layer method that calls a IQueryable method on my repository and returns a IEnumerable containing the entities. I also need to return the total record count so I can calculate the paging links.
How should I return both the int and IEnumerable from my service method?
- Use a out parameter on the method for the total row count
- Create a separate class that includes the total row count as a property
- Move the paging LINQ query out of the service layer (expose the IQueryable from the repo on the service layer)
- Create a full separate method on the service layer that does a new query just for count.
All of these should work, but which one is the cleanest?
UPDATE: Here is some clarification of the architecture. If this is wrong, then please tell me better way (eg - do the paging in the presentation layer instead of service layer,etc)
Repo layer:
returns IQueryable of DbSet, abstracts the db access from the presentation layer
Service layer:
does a LINQ query on the IQueryable to filter and just get the page items as needed using skip and take and returns a IEnumerable (going to also set to List on return to avoid any DbContext lifetime issues)
Presentation layer:
Call the method on the Service layer (getPagedResults(filters, pageNumber, pageSize))
From the looks of it I will also need to add a separate method to get the total results. Was hopeing to do this all in one call.
I would prefer not to bring back all the records to presentation and then page... seems inefficient.
You can do something like this
Then You can write an extension method to use both of these methods
This way you can reuse
GetCollection
andCount
methods independently. You can build the where condition dynamically. Take a look at my answerIf the
Enumerable
you are returning contains all the items, I would do aToList()
on it before returning if from the function. (you can then doCount
with no cost on it) If the function is returning a sub set of the total (usingSkip
andtake
) I would add a seperate function to get the total count.