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 });
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.
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.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With