Próbuję utworzyć opakowanie o numerach QueryableBase i INhQueryProvider, które będą odbierać kolekcję w konstruktorze i wywoływać ją w pamięci zamiast przechodzić do bazy danych. To jest tak, że mogę wyśmiać zachowanie NHibernate's ToFuture()
i poprawnie przetestować moje klasy.Implementowanie niestandardowego zapytania QueryProvider z zapytaniem w pamięci
Problem polega na tym, że mam do czynienia z przepełnieniem stosu z powodu nieskończonej rekurencji i staram się znaleźć przyczynę.
Oto moja realizacja:
public class NHibernateQueryableProxy<T> : QueryableBase<T>, IOrderedQueryable<T>
{
public NHibernateQueryableProxy(IQueryable<T> data) : base(new NhQueryProviderProxy<T>(data))
{
}
public NHibernateQueryableProxy(IQueryParser queryParser, IQueryExecutor executor) : base(queryParser, executor)
{
}
public NHibernateQueryableProxy(IQueryProvider provider) : base(provider)
{
}
public NHibernateQueryableProxy(IQueryProvider provider, Expression expression) : base(provider, expression)
{
}
public new IEnumerator<T> GetEnumerator()
{
return Provider.Execute<IEnumerable<T>>(Expression).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class NhQueryProviderProxy<T> : INhQueryProvider
{
private readonly IQueryProvider provider;
public NhQueryProviderProxy(IQueryable<T> data)
{
provider = data.AsQueryable().Provider;
}
public IQueryable CreateQuery(Expression expression)
{
return new NHibernateQueryableProxy<T>(this, expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new NHibernateQueryableProxy<TElement>(this, expression);
}
public object Execute(Expression expression)
{
return provider.Execute(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return provider.Execute<TResult>(expression);
}
public object ExecuteFuture(Expression expression)
{
return provider.Execute(expression);
}
public void SetResultTransformerAndAdditionalCriteria(IQuery query, NhLinqExpression nhExpression, IDictionary<string, Tuple<object, IType>> parameters)
{
throw new NotImplementedException();
}
}
Edit: mam rodzaj zorientowali się problem. Jeden z argumentów do expression
jest moim niestandardowym zapytaniem. Gdy to wyrażenie jest wykonywane przez dostawcę, wywołuje nieskończoną pętlę wywołania między CreateQuery
i Execute
. Czy można zmienić wszystkie odwołania do moich niestandardowych zapytań do kwerendy opakowanej przez tę klasę?
Czy kiedykolwiek to rozgryzłeś? –
Nie, w końcu stworzyłem własne 'ToFuture', które nazwał NH' ToFuture' w kodzie produkcyjnym i 'ToList' w kodzie testowym. Ale domyślam się, że musiałbyś napisać gościa do wyrażenia, aby ręcznie wymienić parametry. To była moja następna próba. –
@CallumBradbury, jeśli nadal potrzebujesz, myślę, że udało mi się z niego kpić. Sprawdź odpowiedź. –