2013-06-07 20 views
6

Zaimplementowałem proste klasy IQueryable i IQueryProvider, które zbierają dane statystyczne o drzewach wyrażeń LINQ. Ta część działa dobrze. Następnie chciałbym przekazać drzewo wyrażeń do domyślnego dostawcy LINQ-to-Object do oceny, ponieważ nie muszę wykonywać go inaczej. W zamówieniu chciałbym, aby mój dostawca zebrał statystyki jako efekt uboczny, przekazując zapytanie do domyślnej implementacji LINQ.Dostawca przejść LINQ?

Jednak mam trudności z uzyskaniem dojścia do domyślnego dostawcy. Myślałem, że może po prostu zaoszczędzić odniesienie do pierwotnego IEnumerable kolekcji, a następnie powrócić do domyślnego dostawcy (z moim zwyczajem IQueryable) jak:

IQueryProvider IQueryable.Provider 
{ 
    get { return _my_provider.OriginalIEnum().AsQueryable().Provider; } 
} 

ale to nie działa poprawnie. Kod ostatecznie rzuca StackOverflowException. To, co robię, to dzieje się tak, że środowisko wykonawcze LINQ pobiera dostawcę z powyższej metody, następnie pobiera drzewo wyrażeń z mojego niestandardowego IQueryable, a następnie zauważa, że ​​najwyższy poziom wyrażenie to mój zwyczaj IQueryable. Tak więc rozpoczyna się proces od nowa, próbując znaleźć odpowiedniego dostawcę. Robi to bez końca, dopóki nie pojawi się przepełnienie stosu.

W tej chwili jedyne, co mogę wymyślić, to wymyślić innego użytkownika, który tworzy inne drzewo wyrażeń z usuniętymi niestandardowymi węzłami IQueryable, aby środowisko wykonawcze LINQ wywoływało domyślnego dostawcę. To sporo pracy, ponieważ muszę odwiedzić każdy liść, aby upewnić się, że nie ma zagnieżdżonych wyrażeń Call, które ponownie wywołują moje niestandardowe IQueryable. Czy istnieje prostsze podejście?

Dzięki za pomoc.

+0

Więc czy masz jakieś rekurencje, w których dostawca się sam? – gunr2171

+0

Dokładnie. Co jest zastanawiające, ponieważ uważam, że powinienem dostawać referencje do pierwotnego dostawcy. –

Odpowiedz