Question

I have a list of products coming from a repository. Simple enough. Now I want to add filtering and sorting. Sorting could happen outside of the repository since there are no efficiency gains doing them inside the repository (guess). I couldn't imagine doing filtering outside of the repository since we only want to load records we care about. I would think you would want to create a filter delegate and pass it to the repository.

The below code is pseudo C# code. What would functioning code look like to sort / filter?

The process below is really centered around passing delegates to the repository to filter:

Product myProduct = Repo.GetProducts( filter );

(if this were MS MVC, this code would exist in the controller):

Setup a filter:

//TODO: Need filter class definition
var filter = new Filter(); // made up object class for now
filter.AddCondition( field, operator, value);  // do this for each filter condition
filter.AddCondition( Product.Name, contains, "Hammer"); // Product.Name ?? (Example)

Product myProducts = Repo.GetProducts( filter ); // the Product call **FILTER**

Setup a sort:

// TODO: Need sort class definition
var sort = new Sort(); // another made up object class for now
sort.AddOrder( field, priority, sequenceUp) // Sequence enum is ascending/descending
sort.AddOrder( Product.Name, 1, ascending) // (Example) **SORT**

myProducts.AddSort(sort);

Return a view model:

// Next part strips off unnecessary fields for view (Presentation model)
// So we are not sending a huge data model to the view (hopefully good)
// TODO: Replace string with Service? function to extract a miniProduct from Product

MiniProduct myMinis = MakeMiniProductsFrom( myProducts);  // Service?

// Determine response type (XML, JSON, HTML View) and return appropriate data
// use "x-requested-by" as per Rob Conery noted below
if (Request.IsAjaxRequest()) return Json(myMinis);
else return View(myMinis);

As you can see, this code needs some help. I am really looking for sort and filter class code that could make this work, or links to outside sources. I assume sorting and filtering are a standard practice within DDD and design patterns, thus the question. Assume Product is a plain old e-commerce product ;) Rob Conery's Ajax notes are here

Thanks.

Was it helpful?

Solution

Ideally, you'll probably want to do the sorting and the filtering inside the repository. This is particularly important if you're loading large collections, since the DB will most likely be able to sort more efficiently than you can do, and return the sorted results directly.

The IQueryable<T> interface is designed to handle this cleanly - it's the basis for Entity Framework, LINQ to SQL, and other databases with a LINQ provider. The nice thing about trying to support (at least at some level) IQueryable<T> is this lets you use your repository in a very standard way. For example, your pseudocode, using IQueryable<T>, might look more like:

IList<Product> myProducts = Repo.Products.Where( p => p.Category == theCategoryToFind ).OrderBy( p => p.Name );

Or, optionally, just:

var products = from p in Repo.Products
               where p.Category == theCategory
               order by p.Name
               select p;

I recommend looking at how some of the LINQ-oriented data access technologies work - there are quite a few open source options, such as Subsonic (as well as many commercial options) that may provide clues as to how you can better design this for usability.

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