views:

1616

answers:

1

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?

+1  A: 

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.

Marc Gravell
Interesting take on this. However var qry = myDictionary.Values.AsQueryable().Where(sQuery);would only search the Values of the dictionary which are all objects, so it can still not get to the actual name which is stored in the Keys "CustomerID".With your second suggestion, the closest I could get to get anything working with the dynamic linq library is using:search string like: "Keys["CustomerID"] == 12345", but it still bombs out deeper in the library, since they memberinfo returned is just a reference to the KeysCollection and not the specific value.
Jabezz