Я использую 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>>
и назвать ее в списке.
Любая помощь приветствуется.