Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert IEnumerable<T> to IQueryable<T> where T is unknown

I have a BindingSource whose DataSource (defined as an object) could be any type of IEnumerable class at runtime (such as IList<Foo>). I need to convert it to an IQueryable<T> so that I can pass it in to a generic extension:

IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class

So far I have this:

string order = "Message ASC";
Type thetype = bsTotalBindingSource.DataSource.GetType().GetGenericArguments()[0];
IEnumerable<object> totalDataSource = ((IEnumerable<object>)(bsTotalBindingSource.DataSource));
//Blowing up on this next line with 'System.Linq.Queryable is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.'
MethodInfo asQueryableMethod = typeof(Queryable).MakeGenericType(thetype).GetMethod("AsQueryable", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(IQueryable<>) }, null); 
MethodInfo genericAsQueryableMethod = asQueryableMethod.MakeGenericMethod(thetype);
MethodInfo orderUsingSortExpressionMethod = GetType().GetMethod("OrderUsingSortExpression");
MethodInfo genericUsingSortExpressionMethod = orderUsingSortExpressionMethod.MakeGenericMethod(thetype);
bsTotalBindingSource.DataSource = genericUsingSortExpressionMethod.Invoke(this, new object[] { genericAsQueryableMethod.Invoke(totalDataSource, null), order });

As you can see, the end goal here is to be able to take something from a DataSource, get its RuntimeType of IEnumerable<T> where T can be whatever, then call AsQueryable<T> so it can be passed into a function which accepts an IQueryable<T>.

EDIT After digging around to find specifically the methods I am looking for I have gotten a bit farther on the problem. It now looks like this:

string order = "Message ASC";
Type thetype = bsTotalBindingSource.DataSource.GetType().GetGenericArguments()[0];
//Returns the AsQueryable<> method I am looking for
MethodInfo asQueryableMethod = typeof(Queryable).MakeGenericType(thetype).GetMethods()[1]; 
MethodInfo genericAsQueryableMethod = asQueryableMethod.MakeGenericMethod(thetype);
MethodInfo orderUsingSortExpressionMethod = typeof(SortExtension)GetType().GetMethods()[0];
MethodInfo genericUsingSortExpressionMethod = orderUsingSortExpressionMethod.MakeGenericMethod(thetype);
bsTotalBindingSource.DataSource = genericUsingSortExpressionMethod.Invoke(this, new object[] { genericAsQueryableMethod
//blows up here with 'Object of type 'System.RuntimeType' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[LogRecordDTO]'.'
.Invoke(bsTotalBindingSource.DataSource, new object[] {thetype}), order });
like image 559
Dominick O'Dierno Avatar asked Aug 24 '12 12:08

Dominick O'Dierno


People also ask

What is the difference between IEnumerable T and IQueryable T >?

The main difference between IEnumerable and IQueryable in C# is that IQueryable queries out-of-memory data stores, while IEnumerable queries in-memory data. Moreover, IQueryable is part of . NET's System. LINQ namespace, while IEnumerable is in System.

Is IQueryable faster than IEnumerable?

IQueryable is faster than IEnumerable. In addition to Munesh Sharma's answer:IEnumerable loads data in-memory and then apply filters to it one by one but IQueryable apply filters all at once and return the result.

What is difference between IEnumerable and IQueryable in LINQ?

In LINQ to query data from database and collections, we use IEnumerable and IQueryable for data manipulation. IEnumerable is inherited by IQueryable, Hence IQueryable has all the features of IEnumerable and except this, it has its own features. Both have its own importance to query data and data manipulation.


1 Answers

You say you want to convert IEnumerable<T> to IQueryable<T> where T's type is unknown.

private void Test<T>(IEnumerable<T> x)
{
    var queryableX = x.AsQueryable();
}

NOTE: you need to be using System.Linq.

like image 119
PeteGO Avatar answered Sep 30 '22 09:09

PeteGO