Przeczytałem około 30 pytań przepełnienia stosu i około 20 blogów i nie mogę znaleźć odpowiedzi. To powiedziawszy, jestem pewien, że odpowiedź, której wymagam, jest tam dostępna, więc jeśli wiesz o tym, powiedz to (proszę zauważyć ostatni akapit/zdanie dotyczące odpowiedzi, które nie pasują do mojego wymogu). Dzięki!Wyrażenie <Func <TEntity, bool >> zagnieżdżanie, które działa z Entity Framework
Jestem utrzymujących instancje klas, które mają podobny kształt do:
public class Data {
public int Id { get; set; }
}
public class Container {
public int Id { get; set; }
public Data Data { get; set; }
}
Obecnie zapytania są zapisywane znaleźć Kontenery przez warstwę abstrakcji, która wymaga wyrażenia lambda przyjmującą pojemnik i powracającego bool (źródłowe). Nie zaakceptuje IQueryable, mimo że Entity Framework 5 jest ORM z wyboru.
Moim zadaniem jest przedstawienie powierzchni API opartej na wyrażeń Lambda, które akceptują typ danych. Nie mogę zmienić warstwę abstrakcji (muszę przekazać predykat, który akceptuje pojemniku), więc staram się przekształcić wyrażenie otrzymam jako:
Expression<Func<Data , bool>>
to:
Expression<Func<Container , bool>>
dodałem dodatkową metodę w moim repozytorium klasy, takie jak:
public Container Find(Expression<Func<Data , bool>> predicate) {
IEnumerable<Container> result = QueryStrategy.Fetch(c => predicate.Compile().Invoke(c.Data));
return result.FirstOrDefault();
}
ten uzupełnia istniejące metody znajdują się:
public Container Find(Expression<Func<Container , bool>> predicate) {
IEnumerable<Container> result = QueryStrategy.Fetch(predicate);
return result.FirstOrDefault();
}
Kiedy dawny metoda jest wykorzystywana produkuje następujący wyjątek:
LINQ jednostki nie zna metody „Boole'a Invoke (Container.Data) metody”, i ten sposób nie może być przekłada się na ekspresji w sklepie.
Próbowałem różne rzeczy z klas Ekspresji ja po prostu nie widzę sposobu na mapie:
Expression<Func<Data , bool>>
to:
Expression<Func<Container , bool>>
Bez użycia Invoke, który nie jest obsługiwany przez Entity Framework (ale działa z opcją w pamięć przeliczalne dane).
Czy ktoś może mi pomóc uzyskać powyższy scenariusz przy użyciu wyrażeń?
Rozumiem, że być może uda mi się skorzystać z biblioteki LinqKit, aby rozwiązać ten problem, ale naprawdę chcę rozwiązać ten problem, nie wprowadzając biblioteki stron trzecich.
AKTUALIZACJA: Starając się przedstawić uproszczony problem, sugerowałem (początkowo używając DbContext w przykładowym kodzie), że kod będzie miał dostęp do IQueryable i/lub będzie odpowiedni do używania AsExpandable LinqKit(). W rzeczywistości tak nie jest - klasa repozytorium nie może używać rozszerzeń specyficznych dla IQueryable lub jakichkolwiek dostawców. Zmodyfiowałem powyższe przykłady i mam nadzieję, że dzięki temu sprawy staną się jaśniejsze.
Ten problem ten rozwiązano
Czy wymagane jest filtrowanie kontenerów przez twoje wyrażenie Func ma miejsce w bazie danych? –
Dobre pytanie - tak, jest. – FantasticJamieBurns
Czy jest jakiś szczególny powód, dla którego nie chcesz korzystać z biblioteki innej firmy? Jak wspomniano powyżej, LinqKit może obsłużyć komponowanie wyrażeń w sposób jaki chcesz; zrobienie tego bez LinqKita prawdopodobnie wymagałoby powielenia wielu jego funkcji. –