The .AsQueryable() extension method returns an instance of the EnumerableQuery<T> class of the wrapper if it is called because IQueryable<T> has not yet been.
This wrapper class has an .Enumerable property with internal access that provides access to the source object that .AsQueryable() was called to. Therefore, you can do this to return the original dictionary:
var dict = new Dictionary<int, int>(); dict.Add(1,1); var q = dict.AsQueryable(); Type tInfo = q.GetType(); PropertyInfo pInfo = tInfo.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance) .FirstOrDefault(p => p.Name == "Enumerable"); if (pInfo != null) { object originalDictionary = pInfo.GetValue(q, null); Console.WriteLine(dict == originalDictionary);
However, this is usually a pretty bad idea. internal members have access to them for some reason, and I don't think there is any guarantee that the internal implementation of .AsQueryable() will not change at some point in the future. Therefore, your best bet is to either find a way to make the source dictionary available, or go ahead and make a new one.
One possible workaround (which is not big) is to make your own wrapper class a dictionary wrapper:
private class DictionaryQueryHolder<TKey, TValue> : IQueryable<KeyValuePair<TKey, TValue>> { public IDictionary<TKey, TValue> Dictionary { get; private set; } private IQueryable<KeyValuePair<TKey, TValue>> Queryable { get; set; } internal DictionaryQueryHolder(IDictionary<TKey, TValue> dictionary) { Dictionary = dictionary; Queryable = dictionary.AsQueryable(); } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return Queryable.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public Expression Expression { get { return Queryable.Expression; } } public Type ElementType { get { return Queryable.ElementType; } } public IQueryProvider Provider { get { return Queryable.Provider; } } }
This will act as a wrapper for the IQueryable<T> dictionary and provide access to the original dictionary. But, on the other hand, anyone trying to get a dictionary should have known that there were typical type parameters (e.g. <string, string> , <int, string> , etc.) in order to successfully execute it.
Jlrishe
source share