R – How to transfer the execution of a Expression created by an IQueryable object to a IEnumerable

expressionienumerableiqueryablelinq

In my code I'd like to make my repositories IQueryable. This way, the criteria for selection will be a linq expression tree.

Now if I want to mock my repository in theorie this is very easy : just implement the interface of my repository (which is also a IQueryable object).

My mock repository implementation would be only a in memory collection, but my question is : Do you know an easy way to implement the IQueryable interface of my mock, to transfer the query to my in-memory collection (IEnumerable) ?

Thanks for your response,

Some precision

The client object of my repository will use my repository this way :

var result = from entry in MyRepository where entry.Product == "SomeProduct" select entry;

What does ToList or AsEnumerable is to execute the query and return the result as a List or as a IEnumerable. But I have to implement the IQueryable interface on my repository, with a IQueryProvider which transform the expression in a call to a IEnumerable object.

Solution

The implementation of the solution is delegating call to IQueryable to my inmemory collection with AsQueryable.

public class MockRepository : IQueryable<DomainObject>
    {
        private List<DomainObject> inMemoryList = new List<DomainObject>();

        #region IEnumerable<DomainObject> Members

        public IEnumerator<DomainObject> GetEnumerator()
        {
            return inMemoryList.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return inMemoryList.GetEnumerator();
        }

        #endregion

        #region IQueryable Members

        public Type ElementType
        {
            get
            {
                return inMemoryList.AsQueryable().ElementType;
            }
        }

        public Expression Expression
        {
            get
            {
                return inMemoryList.AsQueryable().Expression;
            }
        }

        public IQueryProvider Provider
        {
            get
            {
                return inMemoryList.AsQueryable().Provider;
            }
        }

        #endregion
    }

Best Solution

Use AsQueryable on your mocks. Now they're queryable and you can treat them like any other queryable.