Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LINQ Dynamic Query Library with Dictionary<string, object> and .AsQueryable()

In one of my previous questions about using dynamically built up strings (where clauses) and using them in LINQ, I was guided towards the LINQ Dynamic Query Library Dynamic LINQ.

The first issue was that it only applies to IQueryable, this however can be overcome by using the .AsQueryable() extension method on any IEnumerable.

The problem I ran into was that Dynamic LINQ is looking for a Property called "CustomerID" (or whatever was passed in to the string predicate for dynamic linq) on my Dictionary. Which obviously won't work since a Dictionary only has Keys and Values.

So thinking I'm being clever, I created a class extending : Dictionary<string, object>, ICustomTypeDescriptor`.

This allowed me to override GetProperties() on the type. Which is great. I can now iterate the Dictionary keys and add them to a PropertyDescriptorCollection which gets returned.

But then I ran into another problem. Throughout the Dynamic LINQ library, they work with 'Expression instance' which only contains a Type. But for my CustomTypeDescriptor solution to work I need an actual instance of the Type, before I can apply TypeDescriptor.GetProperties(instance, false).

So getting to the actual question. Taking all the above information into account, how do I apply a custom where clause in string format "CustomerID=1234 AND Quantity >= 10000" to a LINQ query if the data is stored in a Dictionary with Key-Value pairs.

My current solution is transforming the data into a DataTable and using the .Select(query) method. Which works, but I'm interested in finding other solutions. Especially for benchmarking purposes.

Any ideas?

like image 396
Jabezz Avatar asked Aug 20 '09 08:08

Jabezz


1 Answers

Firstly - if you you access a dictionary in this way, then you aren't using it as a dictionary - have you tried:

var qry = myDictionary.Values.AsQueryable().Where(sQuery);

(note that if you are using object, you'll probably want a Cast<Customer> or OfType<Customer> in there somewhere)

Otherwise:

The T in IEnumerable<T> (and hence also for IQueryable<T> after calling the AsQueryable() extension method) for a Dictionary<TKey,TValue> is KeyValuePair<TKey,TValue> - so you should be able to use Where("Value.CustomerID == 12345") or something similar.

like image 143
Marc Gravell Avatar answered Nov 03 '22 19:11

Marc Gravell