3

I have a Query Extender, which has a CustomExpression that I want to use to do some filtering on my datasource.

This is in a DynamicData website so I don't know the object type(current entity) at compile time. Say I knew the object type at compile time, then I could do something like this:

protected void GameFiltering(object sender, CustomExpressionEventArgs e)
{
        e.Query = e.Query.Cast<Resource>().Where(x => x.GameId == GameId);
}

I can get the type I need from e.Query.ElementType. Now I just to send the ElementType as a generic parameter to the Cast method and then call the linq method Where.

I'm gonna assume that every Type is going to have a GameId property which I'll want to filter by.

MethodInfo method = e.Query.GetType().GetMethod("Cast").MakeGenericMethod(new Type[] { e.Query.ElementType });
var castedQuery = method.Invoke(e.Query, null);

This is how I call the cast method with reflection, but I don't know how I can call the linq method on the resulting object.

Adrian Buzea
  • 826
  • 2
  • 11
  • 33
  • have you tried using [dynamic](https://msdn.microsoft.com/de-de/library/Dd264741.aspx). – Jan Unld Aug 31 '15 at 09:27
  • 2
    possible duplicate of [How do I invoke an extension method using reflection?](http://stackoverflow.com/questions/1452261/how-do-i-invoke-an-extension-method-using-reflection) – InvisiblePanda Aug 31 '15 at 09:27
  • The answer in the link above contains a description on how to call the correct `Where` overload via Reflection. Basically, you have to loop through all the existing `Where` methods defined on `System.Linq.Enumerable` and search for the fitting one. Then build a `Func` to pass as parameter. – InvisiblePanda Aug 31 '15 at 09:31
  • If all your types have a property `GameID` why not implementing a common interface and cast to that. Then you can call `Where` on that instance. – MakePeaceGreatAgain Aug 31 '15 at 09:39
  • because they are generated automatically from the database via Entity Framework. – Adrian Buzea Aug 31 '15 at 09:48
  • Sure, but you can however cast to that interface instead of the actual type. Hust use `Enumerable.Cast` for the interface instead od the database-type and you get what you need. – MakePeaceGreatAgain Aug 31 '15 at 09:51

1 Answers1

2

If you assume all items have the property, you don't need to cast them.

protected void GameFiltering(object sender, CustomExpressionEventArgs e)
{
    e.Query = e.Query.Where(obj => (int)obj.GetType().GetProperty("GameId").GetValue(obj, null) == GameId)
}
Robert Fricke
  • 3,637
  • 21
  • 34
  • Interesting solution. I tried this: e.Query = e.Query.Cast().Where(x => (short)x.GetType().GetProperty("GameId").GetValue(x, null) == GameId); Still have to cast to something otherwise I can't call Where on e.Query. This works but when I try to do the DataBind() on my gridview I get an error saying it was expecting an QueryObject of type Resource but it got a QueryObject of type Object – Adrian Buzea Aug 31 '15 at 11:08
  • What type is `e.Query`? – Robert Fricke Aug 31 '15 at 11:17
  • {System.Data.Entity.Core.Objects.ObjectQuery} – Adrian Buzea Aug 31 '15 at 11:20