views:

34

answers:

0

I'd like to pass around a custom IQueryable object to repository methods. Example:

// a fake query to generate an expression
public class MockQuery<T> : IOrderedQueryable<T>
{
    // implement my own query provider internally 
}

public class EFRepository : IRepository<MyType>
{
    public IList<MyType> ExecuteQuery(IQueryable<MyType> query)
    {
        using (var ctx = new EFModelContext())
        {
            var oq = SomeHelper.BuildObjectQuery(query);
            oq.Include("Child");
            return oq.ToList();
        }
    }    
}

// sample client method 
public IQueryable<MyType> GetStuff()
{
    var mockQuery = new MockQuery<MyType>();

    mockQuery.OnExecuting += (args) => 
    {
        var rep = new EFRepository();
        mockQuery.DataList = rep.ExecuteQuery(mockQuery);
    };

    return
        from e in mockQuery 
        where e.Foo == "bar"
        orderby e.Biz ascending
        select e;
} 

So the devil is the details of course, BuildObjectQuery would somehow take the .Expression as it exists in the source IQuery and then use to setup the object query. The problem is ObjectQuery is sealed and there isn't a way for me to pass that along. Has anyone done something similar?

My design goal is to extend the MockQuery with events that I can handle before the provider Execute is called to handle any service calls, logging or even setup the execution of some repository implementation. In a sense, I'm removing the need for a real query provider in MockQuery and giving that responsibility to the client.