var blog = new ThoughtStream(me); RSS 2.0
 Thursday, June 19, 2008

I'm currently working on a search screen for a shipment tracking system.  At the bottom of this screen, there are 4 checkboxes that will determine whether or not we are supposed to display Imports, Exports, Air shipments, or Ocean shipments - in whatever combination the user wants:

image

Down in the depths of the search process, I am creating a "finder" object, as Ayende talked about quite a while back. In this object, I have to account for the checkbox values here - whether or not the user wants to display whatever types of shipment (import or export) and/or the method of shipment (air or ocean). What gets really interesting is that when a box is un-checked, I should not show that particular type or method.

A quick analysis of these 4 checkboxes will come up with the following variants that must be accounted for when building the query.

  1. Show Imports Only
    1. Ocean and Air
    2. Ocean only
    3. Air Only
  2. Show Exports Only
    1. Ocean and Air
    2. Ocean only
    3. Air only
  3. Show Imports and Export
    1. Ocean and Air
    2. Ocean only
    3. Air only
  4. Show no imports or exports (returns no results)
  5. Show no ocean or air (returns no results)

All totaled up, that's 11 different query variants that have to be accounted for.

The end result of my query build methods is the following:

private void AddShipmentMethodCriteria(DetachedCriteria criteria)
{
    ICriterion air = Restrictions.Eq("ShipmentMethod", "Air");
    ICriterion ocean = Restrictions.Eq("ShipmentMethod", "Ocean");
 
    if (searchCriteria.ViewAirShipments && searchCriteria.ViewOceanShipments)
        criteria.Add(Restrictions.Or(air, ocean));
    else
    {
        if (searchCriteria.ViewAirShipments)
            criteria.Add(air);
        else
            criteria.Add(Restrictions.Not(air));
 
        if (searchCriteria.ViewOceanShipments)
            criteria.Add(ocean);
        else
            criteria.Add(Restrictions.Not(ocean));
    }
}
 
private void AddShipmentTypeCriteria(DetachedCriteria criteria)
{
    ICriterion import = Restrictions.Eq("ShipmentType", "Import");
    ICriterion export = Restrictions.Eq("ShipmentType", "Export");
 
    if (searchCriteria.ViewImports && searchCriteria.ViewExports)
        criteria.Add(Restrictions.Or(import, export));
    else
    {
        if (searchCriteria.ViewImports)
            criteria.Add(import);
        else
            criteria.Add(Restrictions.Not(import));
 
        if (searchCriteria.ViewExports)
            criteria.Add(export);
        else
            criteria.Add(Restrictions.Not(export));
    }
}

By having the first If statement check for both 'Import' and 'Export' being requested, we can properly create our query to show both of them via the Restrictions.Or() criteria. Additionally, we have to account for either or both of them not being checked and explicitly call them out to say that we do not want to show whichever one is not selected. The same is true for the 'Air' and 'Ocean' shipment methods.

The end result is that the user can select or un-select whichever shipment methods and shipment types they want, resulting in the correct data being displayed.

...

On a side note, there's probably some abstraction that I could create where I pass in the ICriterions and the boolean flags to help reduce code redundancy but that's not the point of this post. I'm really trying to illustrate the complex logic used in creating the correct NHibernate ICriteria/DetachedCriteria, and the analysis that you need to undertake for what looks like the most simple of situations. After all, how hard could it be to create a query based on 4 check boxes? ... more difficult than you might imagine, at first. Take the time to analyze even simple scenarios like this.

Thursday, June 19, 2008 10:28:17 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Analysis and Design | Data Access | NHibernate
Tracked by:
"Specifications and Lambda Expressions - a quick sample spike" (ThoughtStream.Cr... [Trackback]

Comments are closed.
Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<December 2008>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Derick Bailey
Sign In
Statistics
Total Posts: 91
This Year: 91
This Month: 0
This Week: 0
Comments: 40
Themes
Pick a theme:
All Content © 2008, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)