Dynamic Linq Queries

This time I wanted to share with you about a new feature, or a new way to use Linq. To set things straight this article has nothing related to the dynamic key word introduced in C# 4.0, so if you were looking for the dynamic keyword in action, that’s the time to stop reading.

This paper is more about syntactic sugar, and using Expression trees to have a clean way of writing Linq expressions, specifically when you don’t know what the predicate for your Lambda expression is going to be, thus where the “dynamic” comes into play. We want to write some code that will allow the user to set the filtering, or ordering criteria at runtime, instead of compile time. There are a couple of other Linq operator (Figure 0.0), however but we will talk only about the Where operator, and the OrderBy.

Figure 0.0

For the purpose of this article, I will use a small WPF application to demo the code behind. It has a ListBox where we will display our data, and the feedback of what’s happening when we apply the filters. Moreover I added two ComboBoxes, one contains the properties from our Car class that we want to use for the query, and the second one contains the query operator we want to apply (i.e Where, OrderBy). In addition there is a textbox, used for the Where operator, where we will set some conditions. Figure 1.0 shows a snapshot of the application.

Figure 1.0 : Application snapshot

The data context is very simple, a Car class that has 4 properties: Name, ID, Manufacturer, and year of fabrication. Plus an ObservableCollection<Car> that we will bind our ListBox to.

public class Car

{

   public string Name { get; set; }

   public int ID { get; set; }

   public string Manufacturer { get; set; }

   public int Year { get; set; }

   public override string ToString()

   {
      return String.Format("Name : {0} | ID : {1} | Manufacturer : {2} | Year : {3}", Name, ID, Manufacturer, Year);
   }
}

class DataContext
{
  public ObservableCollection<Car> Cars { get; set; }
}

Imagine now, that we want to filter the data, with a specific manufacturer, or a specific date. The option we have is to write a switch statement around the selected property to filter with; the code would look something like:

</pre>
switch (propertyQueryingFor)
{
  case "Name" :
    _dataContext.Cars = new ObservableCollection<Car>(_cars.Where(c => c.Name == condition));
    break;

  case "ID":

    int id;
    Int32.TryParse(condition, out id);
    _dataContext.Cars = new ObservableCollection<Car>(_cars.Where(c => c.ID == id));
    break;

  case "Manufacturer":
    _dataContext.Cars = new ObservableCollection<Car>(_cars.Where(c => c.Manufacturer == condition));
    break;
}

Figure 2.0: Filtering using Name Property equal to Clio.

Figure 3.0: Ordering the collection using the Year of release.

Well, that works (Figure 2.0, Figure 3.0), but it is a bit cumbersome, and again if you want to add new properties to filter with, you have to add another switch case statement. What if we had a better way of describing this? That’s exactly what the dynamic filtering is for.

We will use a library from the Microsoft samples. You can download the samples by going to:

Visual studio 2010 => Help => Sample => Local sample folder: unzip the CSharpSample.zip. Go to LinqExamples => DynamicQuery. We need only one file Dynamic.cs that I will add to my solution.

The new code is available under a new namespace :

namespace System.Linq.Dynamic;

And our big Switch statement becomes something like:


_dataContext.Cars = new ObservableCollection<Car>(_cars.AsQueryable().OrderBy(propertyQueryingFor));

I mean this is quite powerful, you pass the property you want to filter on as a string, and the “dynamic” orderBy does all the work for you. The same is applicable for the Where operator and the other operator shown in Figure 0.0.

What’s happening behind the scene? Well, actually you can do the same thing using “Expression trees”.

We will give some compile time information to the compiler, to build a data structure (expression tree) that will be compiled at runtime to generate the correct lambda expression as shown in the code below:

var selectedItem = this.PropertyForQuerying.SelectedItem as ComboBoxItem;

var propertyQueryingFor = selectedItem.Content.ToString();

var parameter = System.Linq.Expressions.Expression.Parameter(typeof (Car), "car");

var getter = System.Linq.Expressions.Expression.Property(parameter, typeof (Car).GetProperty(propertyQueryingFor));

var typeOfProperty = typeof (Car).GetProperty(propertyQueryingFor);

var lambda = System.Linq.Expressions.Expression.Lambda<Func<Car, string>>(getter, parameter);

_dataContext.Cars = new ObservableCollection<Car>(_cars.OrderBy(lambda.Compile()));

As you can see this is not complete, since the Func<Car, string> requires that the filtering property to be a String, our code won’t work if we filter with the Year property, since it’s an Int.

Using the Dynamic.cs is more powerful, since it uses the expression trees extensively, and is more generic, moreover you can pass multiple ordering parameters, and it will automatically convert it to an OrderBy followed by ThenBy.

I hope you found this article useful, please let me know if you have questions, or if you want me to send the code for the demo in this article.

Leave a comment

Filed under DotNet

MVP, MVC, MVVM, What is it all about?

MVP, no it is not “Most valuable professional”, it is Model-View-Presenter. This article has been created in my research of understanding more about these acronyms and what they really are. I will try to explain the differences between those three different UI patterns, and really grasp their different usages. One key concept to remember is that behind those patterns we want to achieve a separation of concerns, the GUI should be responsible only for the display; the domain objects should do the rest. Domain objects should not care how they are going to be displayed, and potentially (most likely) be displayed in different ways (views).

Continue reading

Leave a comment

Filed under Design principles

Playing with new feature from C# 3.0

Hello, just a piece of code summarizing the new stuff in C# 3.0


class Program
{
static void Main(string[] args)
{
Func<string, int> returnLength;

//Lambda expression
returnLength = text => text.Length;

Console.WriteLine(returnLength("Hello"));

var films = new List<Film>
{
// Simplified intialization
new Film { Name ="Matrix", Year = 1999},
new Film { Name ="Independance", Year = 2001},
new Film { Name ="Alien", Year = 1993},
new Film { Name ="Zoro", Year = 2008},
new Film { Name ="Shrek", Year = 1996},

};

Action<Film> print = film => Console.WriteLine("Name={0} , Year={1}", film.Name, film.Year);

Console.WriteLine("All movies\n");
films.ForEach(print);

Console.WriteLine("All movies before 2000\n");
films.FindAll(film => film.Year < 2000).ForEach(print);

Console.WriteLine("All movies sorted\n");
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
films.ForEach(print);

Expression args1 = Expression.Constant(2);
Expression args2 = Expression.Constant(3);

Expression add = Expression.Add(args1, args2);

Expression<Func<int>> return5 = () => 5;

Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y);
var compiled = expression.Compile();

Console.WriteLine(compiled("Toutou", "Tou"));
Console.WriteLine(compiled("Toutou", "You"));

Console.WriteLine("\nadded with expression " + return5.Compile());

MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var target = Expression.Parameter(typeof(string), "x");
var methodArg = Expression.Parameter(typeof(string), "y");
Expression[] methodArgs = new[] { methodArg };

Expression call = Expression.Call(target, method, methodArg);

var lambaparameters = new[] { target, methodArg };
var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambaparameters);

Console.ReadLine();
}
}

Leave a comment

Filed under Uncategorized

DataGridView and binding

There was a question on stack overflow about DataGridView and binding.The issue was that he couldn’t bind an ICollection<Object> to the dataSource, I tried a simple example :


var grid = new System.Windows.Forms.DataGridView();
var window = new System.Windows.Forms.Form();
window.Controls.Add(grid);

var bindingsource = new BindingSource();
List<String> list = new List<String> { "fff", "b", "c","d" };
bindingsource.DataSource = list;
grid.DataSource = bindingsource;
window.ShowDialog();

Continue reading

2 Comments

Filed under binding, datagridview, winforms