Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
LINQ (language integrated query) is one of the new features provided with VS 2008 and .NET 3.5. LINQ makes the concept of querying data a first class programming concept in .NET, and enables you to efficiently express queries in your programming language of choice.
One of the benefits of LINQ is that it enables you to write type-safe queries in VB and C#. This means you get compile-time checking of your LINQ queries, and full intellisense and refactoring support over your code:
While writing type-safe queries is great for most scenarios, there are cases where you want the flexibility to dynamically construct queries on the fly. For example: you might want to provide business intelligence UI within your application that allows an end-user business analyst to use drop-downs to build and express their own custom queries/views on top of data.
Traditionally these types of dynamic query scenarios are often handled by concatenating strings together to construct dynamic SQL queries. Recently a few people have sent me mail asking how to handle these types of scenarios using LINQ. The below post describes how you can use a Dynamic Query Library provided by the LINQ team to dynamically construct LINQ queries.
Downloading the LINQ Dynamic Query Library
Included on the VS 2008 Samples download page are pointers to VB and C# sample packages that include a cool dynamic query LINQ helper library. Direct pointers to the dynamic query library (and documentation about it) can be found below:
- VB Dynamic Query Library (included in the \Language Samples\LINQ Samples\DynamicQuery directory)
- C# Dynamic Query Library (included in the \LinqSamples\DynamicQuery directory)
Both the VB and C# DynamicQuery samples include a source implementation of a helper library that allows you to express LINQ queries using extension methods that take string arguments instead of type-safe language operators. You can copy/paste either the C# or VB implementations of the DynamicQuery library into your own projects and then use it where appropriate to more dynamically construct LINQ queries based on end-user input.
Simple Dynamic Query Library Example
You can use the DynamicQuery library against any LINQ data provider (including LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer, etc). Instead of using language operators or type-safe lambda extension methods to construct your LINQ queries, the dynamic query library provides you with string based extension methods that you can pass any string expression into.
For example, below is a standard type-safe LINQ to SQL VB query that retrieves data from a Northwind database and displays it in a ASP.NET GridView control:
Using the LINQ DynamicQuery library I could re-write the above query expression instead like so:
Notice how the conditional-where clause and sort-orderby clause now take string expressions instead of code expressions. Because they are late-bound strings I can dynamically construct them. For example: I could provide UI to an end-user business analyst using my application that enables them to construct queries on their own (including arbitrary conditional clauses).
Dynamic Query Library Documentation
Included with the above VB and C# Dynamic Query samples is some HTML documentation that describes how to use the Dynamic Query Library extension methods in more detail. It is definitely worth looking at if you want to use the helper library in more depth:
Download and Run a Dynamic Query Library Sample
You can download and run basic VB and C# samples I've put together that demonstrate using the Dynamic LINQ library in an ASP.NET web-site that queries the Northwind sample database using LINQ to SQL:
You can use either Visual Web Developer 2008 Express (which is free) or VS 2008 to open and run them.
Other Approaches to Constructing Dynamic LINQ Queries
Using the dynamic query library is pretty simple and easy to use, and is particularly useful in scenarios where queries are completely dynamic and you want to provide end user UI to help build them.
In a future blog post I'll delve further into building dynamic LINQ queries, and discuss other approaches you can use to structure your code using type-safe predicate methods (Joseph and Ben Albahari, authors of the excellent C# 3.0 In a Nutshell book, have a good post on this already here).
Hope this helps,
Scott