2013-03-15 30 views
7

I obecnie "stronicowanie" przez tabelę ("Tabela 1"), która ma następujące pola {Polityka, Nazwa, Kwota, Data} i może być wiele rekordów w "Tabela 1" dla polityka, jak następuje:Pomiń obiekt Entity przez grupę przez

return context.Table1s.Orderby(i => i.Policy) 
         .Skip(endingRecord).Take(page) 
         .ToList(); 

Jak bym to zrobił, gdybym chciał pierwszej grupy przez polityki i następnie przejść i wziąć na odrębnych polityk (zasadniczo stara się zapewnić, że „strona” zawiera wszystkie rekordy zasady zawarte na stronie)?

Używam C#, framework entity i preferuję składnię "lambda", jeśli to możliwe.

+1

co jest nie tak z ich grupowaniem (GroupBy) po wykonaniu tego zapytania? – sergioadh

+0

ponieważ jeśli mam politykę, która ma dwa rekordy, jeden kończy się na numerze 50000, a drugi na 50001, jeśli strona jest na stronie o 50000, nie otrzymam 50001 rekordu i chcę go. – AWeim

Odpowiedz

4
return context.Table1s.GroupBy(i => i.Policy) 
         .Select(g => g.First()) 
         .Orderby(i => i.Policy) 
         .Skip(endingRecord).Take(page) 
         .ToList(); 

który generuje SQL tak (próbki z LINQPad dla LINQ to SQL):

SELECT [t4].[test], [t4].[Name], [t4].[Policy], [t4].[Amount], [t4].[Date] 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t3].[Policy]) AS [ROW_NUMBER], [t3].[test], [t3].[Name], [t3].[Policy], [t3].[Amount], [t3].[Date] 
    FROM (
     SELECT [t0].[Policy] 
     FROM Table1s AS [t0] 
     GROUP BY [t0].[Policy] 
     ) AS [t1] 
    OUTER APPLY (
     SELECT TOP (1) 1 AS [test], [t2].[Name], [t2].[Policy], [t2].[Amount], [t2].[Date] 
     FROM Table1s AS [t2] 
     WHERE (([t1].[Policy] IS NULL) AND ([t2].[Policy] IS NULL)) OR (([t1].[Policy] IS NOT NULL) AND ([t2].[Policy] IS NOT NULL) AND ([t1].[Policy] = [t2].[Policy])) 
     ) AS [t3] 
    ) AS [t4] 
WHERE [t4].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1 
ORDER BY [t4].[ROW_NUMBER] 
+0

Otrzymuję następujący błąd - Metoda "Pierwsza" może być używana tylko jako operacja zapytania końcowego. Zamiast tego należy użyć metody "FirstOrDefault" w tym wystąpieniu. – AWeim

+1

@Airim like like EF sugests :) Zamiast tego użyj FirstOrDefault. Każda grupa będzie miała co najmniej jeden przedmiot, więc nie ma różnicy w tym przypadku –

0

Można użyć metod SkipWhile i TakeWhile, ale trzeba by je rozdzielić następująco:

var policyStart = context.Table1s.Orderby(i => i.Policy).ToList().SkipWhile(i => i.Policy == endingRecord.Policy); 
var firstPolicy = policyStart.FirstOrDefault().Policy; 
return policyStart.TakeWhile(i => i.Policy == firstPolicy).ToList(); 
+0

Nie chcę wykonywać jednej polisy naraz. Mam politykę 107 000 i chciałem zwrócić dane dla 10 000 polis na raz. – AWeim

+0

Nieważne, że ... Myślę, że wiem, co mówisz ... Spróbuję. – AWeim

+0

Otrzymuję błąd z tym że Linq to Entities nie rekonfiguruje SkipiWhile ... Używam Entity framework – AWeim

1

Poniższa dał mi pożądanych rezultatów

return context.Tables1 
       .Where(i => 
        context.Tables1 
        .GroupBy(t => t.Policy) 
        .OrderBy(t => t.Key) 
        .Skip(previousRecordCount).Take(page) 
        .Select(t => t.Key) 
        .Contains(i.Policy)) 
        .ToList(); 
Powiązane problemy