Po prostu wpadłem na to sam. W moim przypadku problem polega na tym, że zapytanie ma klauzulę .Select(), która powoduje, że tworzone są dalsze relacje, co w efekcie powoduje dalsze filtrowanie zapytania, ponieważ powiązanie wewnętrzne związku ogranicza wynik.
Wygląda na to, że .Count() nie przetwarza części .Select() zapytania.
Więc mam:
// projection created
var ordersData = orders.Select(ord => new OrderData() {
OrderId = ord.OrderId,
... more simple 1 - 1 order maps
// Related values that cause relations in SQL
TotalItemsCost = ord.OrderLines.Sum(lin => lin.Qty*lin.Price),
CustomerName = ord.Customer.Name,
};
var count = ordersData.Count(); // 207
var count = ordersData.ToList().Count // 192
Kiedy porównać SQL Uważam, że count() robi to bardzo prosta suma na tabeli Zamówienia, która zwraca wszystkie rozkazy, natomiast drugie zapytanie jest potworem 100 + linie SQL, które mają 10 wewnętrznych sprzężeń, które są wyzwalane przez klauzulę .Select() (istnieje kilka więcej powiązanych wartości/agregacji pobranych niż pokazano tutaj).
Zasadniczo wydaje się wskazywać, że .Count() nie ponosi .Wybrać() Klauzula pod uwagę, gdy robi swój licznik, więc te same związki, które powodują dalsze ograniczające zestawu wynikowego nie są wypalane na .Count().
byłem w stanie wykonać tej pracy przez jawnie dodawanie wyrażeń metody .Count(), która ciągnąć w niektórych z tych zagregowanych wartości wynikowych, które skutecznie zmuszają je do .Count(), a także zapytania:
var count = ordersData.Count(o=> o.TotalItemsCost != -999 &&
o.Customer.Name != "[email protected]#"); // 207
Kluczem jest upewnienie się, że którekolwiek z pól, które są obliczane lub przyciągane do powiązanych danych i wywołują związek, są uwzględniane w wyrażeniu, które wymusza w Count() uwzględnienie wymaganych relacji w zapytaniu.
Zdaję sobie sprawę, że to total hack i mam nadzieję, że jest lepszy sposób, ale na chwilę to pozwoliło nam przynajmniej uzyskać odpowiednią wartość bez ciągnięcia ogromnych danych za pomocą .ToList().
Czy efQuery IEnumerable lub IQueryable? Także, jeśli mógłbyś opublikować swój rzeczywisty kod, który mógłby pomóc. – Maess
efQuery to 'IQueryable', jest to zapytanie, które nie zostało jeszcze wykonane na bazie danych. Dodałem kod. – ReFocus