Getting Around Some Anonymous Type Headaches with Dynamic LINQ

Here’s something that totally slipped under my radar when it first came out:  Dynamic LINQ.  This lets you specify LINQ predicates (where clauses, order bys, etc.) using strings instead of strongly typed lambda expressions.  For example, you can rewrite the following LINQ query:

var orders = from o in db.Orders
     where o.OrderDate > DateTime.Now.AddDays(-30)
     select o.OrderID, o.OrderDate;

as something like this:

var orders = db.Orders.Where("OrderDate > @0",
     DateTime.Now.AddDays(-30)).Select("new(OrderID, OrderDate)");

Now, I know what you’re saying.  “Why would I want to give up all that strongly-typed goodness?  Isn’t that what LINQ was all about?”  Well, at least for me, this came in handy when dealing with anonymous types.  Since the only way you can pass a LINQ to SQL result (which is usually an IQueryable  anonymous type) to a function is as an IQueryable<T>, there’s no way in that function to specify a strongly typed predicate.  The compiler only knows what properties an anonymously typed object has inside the scope in which the variable is declared.

Since the overload of “Where()” provided by the Dynamic LINQ library (DLL, anyone?) will work with any IQueryable<T>, you can specify predicates on LINQ to SQL results passed into functions, as long as you know what properties the object you passed in has.  Using it reminds me of using the HQL syntax in NHibernate.

You can get the library from the LINQ samples provided by Microsoft here.  It’s just a C# or VB file named Dynamic.(cs/vb) in the LinqSamplesDynamicQuery directory. It includes a bunch of extension methods that provide the extra overloads to the LINQ methods.

Not something I envision using often, since it’s nice to be able to take advantage of the strong typing when you can get it, but nice to know that it’s there if you need it.

2 thoughts on “Getting Around Some Anonymous Type Headaches with Dynamic LINQ

  1. Kshitij

    Can you cast the Linq result using Cast() to IEnumerable?

    do you have to pass it as IQueryable?

    I have not played with Linq to Sql, so this might be a nooption.

    Just asking.

    Kshitij

    Reply
    1. Brian Post author

      @Kshitij

      You can always get an IEnumerable from an IQueryable, but not by casting. There’s actually an extension method on IQueryable called “AsEnumerable()”, and a corresponding extension method on IEnumerable called “AsQueryable()”, so you can switch back and forth to your heart’s content. Translating back and forth doesn’t cause the query to be executed, either. That doesn’t happen until you actually enumerate the collection by doing a foreach over it or calling ToList() or ToArray() on it.

      Brian

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>