Перемешивание IOrderedQueryable и IDocumentQuery - PullRequest
0 голосов
/ 24 мая 2018

Я использую IDocumentClient для извлечения и обновления элементов в коллекции DocumentDB.

Код для получения списка документов, соответствующих условию, выглядит следующим образом:

public static async Task<FeedResponse<T>> GetDocuments<T>(
            this IDocumentClient client,
            string collection,
            Expression<Func<T, bool>> filter)
        {
            IDocumentQuery<T> query = client.CreateDocumentQuery<T>(GetCollectionUri(collection)).Where(filter)
                                            .AsDocumentQuery();
            return await query.ExecuteNextAsync<T>().ConfigureAwait(false);
        }

Чтобы выполнить приведенный выше код для сравнения со списком фиктивных элементов, я создалкласс макета:

public class MockIOrderedQueryable<T> : List<T>, IOrderedQueryable<T>, IDocumentQuery<T>
    {
        public Expression Expression
        {
            get
            {
                var content = this.ToList();
                return content.AsQueryable().Expression;
            }
        }

        public IQueryProvider Provider => new MyProvider<T>(this.ToList());

        public Task<FeedResponse<TResult>> ExecuteNextAsync<TResult>(CancellationToken token = new CancellationToken())
        {
            var tmp = new FeedResponse<TResult>((IEnumerable<TResult>)this);
            return Task.FromResult(tmp);
        }    
    }

Фильтр Where является методом расширения для IQueryable<T>, поэтому мне нужна была реализация, которая выглядит следующим образом:

public class MyQueryable<T> : IQueryable<T>, IDocumentQuery<T>
    {
        private readonly List<T> _list;

        public MyQueryable(List<T> list)
        {
            _list = list;
        }

        public Task<FeedResponse<TResult>> ExecuteNextAsync<TResult>(CancellationToken token = new CancellationToken())
        {
            var tmp = new FeedResponse<TResult>(_list as List<TResult>);
            return Task.FromResult(tmp);            
        }    
    }

А также реализацияиз IQueryProvider, который возвращает экземпляр IQueryable в мой исходный фиктивный класс через CreateQuery:

public class MyProvider<T> : IQueryProvider
    {
        private readonly List<T> _list;

        public MyProvider(List<T> list)
        {
            _list = list;
        }

        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
        {
            return new MyQueryable<TElement>(_list as List<TElement>);
        }        
    }

Для краткости я опустил код для методов, которые выдают NotImplementedException, а также для полейкоторые не используются.

Все это выглядит хорошо, но мне не удалось сделать одну вещь: применить реальную фильтрацию, переданную как Expression in CreateQuery к элементу _list элемента MyProvider,Я попытался вызвать Invoke и получить аргументы, но это не сработало.Выражение, возвращаемое в MockIOrderedQueryable, вероятно, не очень хорошее (.AsQueryable в списке).Я хотел бы добраться до лямбды Expression<Func<T, bool>> и назвать ее в списке.

Любая помощь приветствуется.

...