The code knows no master

From Part 1 of getting Metadata up and running we are now going to work on getting querying an entity set working. But first a quick update. From the last time I left getting the metadata in the processing request and I did move that out into it’s own method.

If this method returns null then we are not dealing with an entity or entity set. From there we will need to switch from IEdmEntityType to the CLR type. For that I’m going to create another interface and create a default implementation for DbContext.

and here is the default implementation. I’m not sold on how I’m looking up the CLR type from metadata of the DbContext and if someone else has a better idea let me know. Or even better answer this stackoverflow question.

Noticed I had to use an Assembly Resolver otherwise Type.GetType() would fail. Now that we have a type I’m going to use a bit of reflection and switch us from a System Type to a generic type. I’m going to store a method handle to the method we want to switch to and grab that in the static constructor since it shouldn’t change. Also I’m going to add a couple more interfaces we haven’t talk about yet but will quickly discuss.

IQueryRootProvider will be used to return the starting point of the IQueryable. IQueryInterceptor is used to add a where clause. I was on the fence on that interface as it could be implemented in IQueryRootProvider but added it for flexibility and since WCF Data Services has something similar.

Pretty simple stuff. For IQueryInterceptor I created a default implementation but it doesn’t rely on DbContext. First I created an attribute called QueryInterceptorAttribute, same name as WCF Data Services.

With the abstract class of QueryInterceptor you can create a class that inherits from it and mark methods with the QueryInterceptor attribute. If the return type of the method is type we are looking for it will auto add the return value to the where clause. If you don’t like this implementation you can just create a different class that implements IQueryInterceptor, that’s the great part. Also word of warning I haven’t tested that code yet 🙂

Now we should be able to hit /api/odata/Customers?$orderby=City&$select=City or /api/odata/Customers. Assuming your DbContext has an Customer Entity Set and property called city 🙂 Next I will be trying to get a single entity but that’s for a Part 3 and we’ll need to dive into ExpressionTrees.