Question

Should I be filtering my IQueryable results from the Domain Service?

For example... My 3 portals (Websites) access the same Domain Service Layer, depending on the type of user it is, I call a specific repository method and return the result,

Current Repository Layer:

    IQueryable<Products> GetAllProductsForCrazyUserNow(CrazyUser id);
    Products GetAProductForCrazyUserNow(CrazyUser id,product id);

    IQueryable<Products> GetProductsForNiceUserNow(NiceUser id);
    Products GetProductsForNiceUserNow(NiceUser id,product id);

Would it be best just to do this in the Repository Layer:

    IQueryable<Products> GetAllProducts();
    Products GetAProduct(product id);

Then within the Domain Service, I simple do the filter i.e.

var Niceman = IQueryable<Products> GetAllProducts().Where(u=> u.Name == "Nice");

NOTE: I have a read only session and session which includes CRUD within the Repository Layer, so please keep that in mind when answering.

Second question: Should I do any filtering at all in the domain service layer? This very layer is the only layer than can amend the Entity i.e. Product.Price == 25.00; This is not delegated to the repository layer.

Was it helpful?

Solution

I normally use the repository layer to do simple CRUD work and have the domain layer perform any business logic or in your case any filtering that is needed before passing that data back to the UI layer.

Separating out the business/filtering logic from the repository layer will help keep things clean. Also, in the future if you move to a different type of data access pattern, then you won't have to change how that code works since it will be separated in your domain layer.

OTHER TIPS

Haroon,

I use extension methods on IQueryable<Classes> OUTSIDE of the repo. in fact, i have a set of classes that i call 'Filters' and they are usually something along these lines:

public static class ProductFilters
{
    public static IQueryable<Products> NiceMan(
        this IQueryable<Products> customQuery, string filterName)
    {
        if (!string.IsNullOrEmpty(filterName))
           customQuery = customQuery.Where(u => u.Name == filterName);
        return customQuery;
    }
   // create lots of other Products based filters here
   // and repeat with seperate IQueryable<Classes> per type
}

usage:

var Niceman = IQueryable<Products> GetAllProducts().NiceMan("Nice");

I find this a good separation of logic and keeps the repo clean. And in answer to the second question, yes, use this filter/extension logic inside the service layer, rather than the repo as well.

I've had this same question myself. My hesitation to putting it in the service layer was that in some cases the filtering process could remove the bulk of the records returned from the repo, and I didn't want to pull more data than necessary from the database.

I ended up moving to NHibernate, and had my repository methods accept DetachedCriteria arguments. I then passed the user information to the service layer and had it perform the filtering not by manipulating an IQueryable but by constructing a DetachedCriteria object and passing it along to the repo, thus modifying the SQL and limiting the database work.

So far it seems to work pretty well, and "feels" right since I have my logic pretty solidly in the service layer with the repo only doing basic CRUD.

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