mardi 1 septembre 2015

Casting object to generic type in order to use IEnumerable.Where

I'm trying to implement some filtering in my Dynamic Data + EF website and I'm using a QueryExtender with a CustomExpression. In the OnQuerying event of the CustomExpression I have access to e.Query(where e is of type CustomExpressionEventArgs) which is the Query that is used to get the data from the database. In order to filter the data I need to make changes to this query.

Now this query is of type System.Data.Objects.ObjectQuery<T>, where T is only known at runtime. I'm going to assume that whatever type T is, it's going to have a property called GameId. What I need to do is do a simple Where LINQ statement on this collection where I filter by that property.

short GameId = Convert.ToInt16(Session["GlobalGameFilter"]);
Type currentType = e.Query.ElementType;
//ObjectQuery implements IQueryable and I want to cast to ObjectQuery<CurrentType> 
MethodInfo method = typeof(Queryable).GetMethod("Cast").MakeGenericMethod(new Type[] { currentType });
var castedQuery = method.Invoke(e.Query, new object[]{e.Query});

This works, now castedQuery is of type ObjectQuery<currentType>

The problem is that in order to use castedQuery.Where() I need to cast it to an IEnumerable<currentType>, I can't just cast it to the non-generic IEnumerable.

I tried calling Where via reflection (from here):

var whereMethods = typeof(System.Linq.Enumerable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");
MethodInfo whereMethod = null;
foreach (var methodInfo in whereMethods)
{
    var paramType = methodInfo.GetParameters()[1].ParameterType;
    if (paramType.GetGenericArguments().Count() == 2)
    {
        whereMethod = methodInfo;
    }
}

whereMethod = whereMethod.MakeGenericMethod(currentType);

var ret = whereMethod.Invoke(castedQuery, new object[] { castedQuery, BuildEqFuncFor<Placement>("GameId", GameId) });

But ret is always an empty collection.





Aucun commentaire:

Enregistrer un commentaire