2016-06-22 8 views
5

Mam dwie tabele:Jak mogę sortować obiekty zwrócone przez EF zgodnie z listą identyfikatorów?

User { 
    PK: UserId 
    ... 
} 

Product { 
    PK: ProductId, 
    FK: UserId 
    ... 
} 

Mam listę ProductId S w formacie losowej. Nie chcę sortować wyniku wyjściowego i chciałbym uwzględnić dane użytkownika również dla każdego identyfikatora produktu.

Poniższy kod dostarcza dane w posortowanym formacie. Jak mogę uniknąć tego sortowania? Chcę, aby lista obiektów była w tej samej kolejności, co nasza lista produktów.

List<Tables.Product> tblProductList = 
    repo.Products 
     .Include("User") 
     .Where(x => productIdList.Contains(x.ProductId)) 
     .ToList(); 
+3

Nie ma czegoś takiego jak domyślne sortowanie . Dopóki nie określisz klauzuli OrderBy, baza danych zwróci obiekty bez zamawiania. * Mogą * pojawić się uporządkowane, ponieważ niektóre operacje (np. Różne) używają Sortuj. Nawet te będą nieuporządkowane, jeśli zapytanie jest wystarczająco drogie, aby je zrównoważyć. –

+0

Co to jest "productIdList"? Coś załadowano z innego stołu lub tylko listę identyfikatorów? –

+0

productIdList zawiera listę identyfikatorów całkowitych. –

Odpowiedz

2

Chcę lista obiektów w tej samej kolejności co naszej liście produktów.

Zakładam przez naszej listy produktów masz na myśli productIdList zmienna użyta do filtrowania.

Nie możesz tego zrobić w LINQ do Entities, więc musisz przełączyć LINQ na Objects i zrobić porządek w pamięci.

Jednym ze sposobów byłoby użyć IndexOf metody:

var tblProductList = 
    repo.Products 
     .Include("User") 
     .Where(x => productIdList.Contains(x.ProductId)) 
     .AsEnumerable() // Switch to LINQ to Objects context 
     .OrderBy(x => productIdList.IndexOf(x.ProductId)) 
     .ToList(); 

innym bardziej wydajnych metod (gdy productIdList jest duża) może być w użyciu pośredniego słownika:

var productsById = 
    repo.Products 
     .Include("User") 
     .Where(x => productIdList.Contains(x.ProductId)) 
     .ToDictionary(x => x.ProductId); 

var tblProductList = productIdList 
    .Select(productId => productsById[productId]) 
    .ToList(); 
+0

Dziękuję jak zawsze :) –

+0

Dla 10 productIdList powyższe zapytanie zajmuje 10 sekund. Czy istnieje sposób, aby to poprawić? –

+0

Ile czasu zajmuje oryginalne zapytanie? –

-1
var tblProductList=(from product in repo.Products 
        join user in repo.Users on product.UserId equals user.UserId 
        select new { Product=product,User=user}).toList(); 
+1

ORMy używają relacji, a nie łączeń. Nie ma absolutnie żadnego powodu, aby używać 'join', gdy relacja jest już zdefiniowana. W rzeczywistości jest to błąd używania połączeń zamiast odwzorowywania relacji –