Most of the projects I work with are very data-intensive. I often need ways to present data filters to users as a part of the project. The data filters have all, in the past, been single-need, single-use objects. However, as time goes on in general, when you have many projects that have similar needs, you realize that the commonalities of the objects create an opportunity to make them all exactly the same, so when this happens, I add a new object to my standard class library.

This is what has happened with Data Filters. I have projects where data is filtered after loading. This is because the data is loaded from perhaps many different sources, and I need to filter a DataTable object. I also have projects where the filtering operation is actually done in the database, i.e. through a SQL query. Some of the applications allow grouping of query lines, and some don’t.

So, the list of operations for a filter line (equals, less than, contains, starts with, etc.) can vary from project to project. The capabilities of each of the filters can vary from project to project. So, I decided to make it all consistent.



The first component object is a DataFilterLine. It is the single logical expression, such as “field x is greater than 5”, or “field y is not blank”, or “field z is greater than 3 days ago”. This is the one that does most of the work, in that it is the only one actually filtering the data. It does this in a method “Evaluate”, which takes in either a data row and returns Boolean as to whether the row meets the filter or not, or a data table, which returns a data table of all rows fitting the line.

Each DataFilterLine includes the following properties:

  • ColumnID
  • DataType
  • Operator
  • Value
  • Negate
  • Conjunction
  • OrderBy



The second component is a DataFilterGroup. It is a collection of DataFilterLine objects. This object will evaluate each DataFilterLine, in order, and perform set operations based on their conjunctions. The object, since it is itself grouped into the parent object DataFilter (described next), also has properties to describe its logic for joining.

Each DataFilterGroup includes the following properties:

  • DataFilterLines (list)
  • Negate
  • Conjunction
  • OrderBy



This object is the parent object. It simply has the DataFilterGroup collection, and when “Evaluate” is called, it simply evaluates each DataFilterGroup, in order, and performs set operations based on their conjunctions.


Because these code files are pretty large, I will not be posting the entire contents here, but will instead link to a download of the three files as a zip file.