2012-02-22 22 views
6

Mam poniższej tabeli:LINQ uzyskać wartość Max z listy

ID Amt Received 
-- ---- -------- 
2 55 N 
2 88 Y 
2 44 N 
3 5 N 
3 9 N 
4 5 N 
5 33 Y 
6 43 N 
7 54 N 

    var result = (from rs in db.Exp 
        where rs.ID == id 
        && rs.Received == true 
        select rs).Max().Any(); 

Biorąc identyfikator, muszę znaleźć max AMT do danego id, a następnie sprawdzić, czy jest Y, jeśli tak, to zwraca wartość true else zwraca false.

Odpowiedz

18

Powinno to zrobić;

db.Exp. 
    Where(x => x.ID == id). 
    OrderByDescending(x => x.Amt). 
    Take(1). 
    Any(x => x.Received == "Y"); 
+0

Nice. Podejrzewam, że ostatnia część powinna być po prostu 'x => x.Received', ale podoba mi się sposób, w jaki obsługuje on puste wyniki. –

+0

@Joachim Isaksson - Podoba mi się rozwiązanie. Muszę dodać kolejny warunek do .Any (x => x.Received == "Y" && x => x.Division == "Accounting"), ale nie pozwala mi to zrobić. Każdy pomysł, dlaczego. Zauważ, że Division nie znajduje się w powyższej tabeli. Zapomniałem o tym zawrzeć –

+0

@NatePet Musisz tylko wpisać 'x =>' raz w lambda, więc powinno to być '.Any (x => x.Received ==" Y "&& x.Division ==" Księgowość ")' –

3

Musisz powiedzieć, co chcesz, aby uzyskać Max.

var result = 
    (from rs in db.Exp 
    where rs.ID == id && rs.Received 
    select rs) 
    .Max(row => row.Amt) == Y; 

I nie trzeba się .Any() w ogóle

0
// "I need to find the max Amt for a given id..." 
var elementWithMaxAmount = 
    db.Exp 
    .Where(x => x.ID == id) 
    .OrderByDescending(x => x.Amount) 
    .FirstOrDefault(); 

// "... and then check if it is Y" 
var result = (elementWithMaxAmount != null && 
       elementWithMaxAmount.Received == "Y"); 
6

Niestety LINQ nie zapewnia "max przez atrybut" metody. MoreLINQ działa z operatorem MaxBy, ale nie można tego oczywiście przetłumaczyć na SQL. Więc jeśli jest to kwerenda LINQ do SQL (lub cokolwiek innego), potrzebujesz innego podejścia. Jeśli to już LINQ to Objects, jednakże:

return db.Exp.Where(rs => rs.ID == id) 
      .MaxBy(rs => rs.Amt) 
      .Received; 

Należy pamiętać, że to, co robi słowa Twojego pytania prosimy:

  • Spośród rekordów z podanym ID ...
  • Znajdź jedną z najwyższą ilością ...
  • I sprawdzić wartość Received

To nie samo jak:

  • Spośród rekordów z podanym ID gdzie otrzymał to prawda ...
  • Znajdź jedną z najwyższą ilością

Należy również zauważyć, spowoduje to zgłoszenie wyjątku, jeśli są zarejestrowane rekordy no z tym identyfikatorem.

Jeśli chcesz to zrobić w LINQ to SQL etc, można prawdopodobnie najlepiej wyłączyć z zamawiającego:

var highest = db.Exp.Where(rs => rs.ID == id) 
        .OrderByDescending(rs => rs.Amt) 
        .FirstOrDefault(); 
return highest != null && highest.Received; 

Robisz nie chcesz to zrobić, jeśli używasz LINQ do obiektów, ponieważ zamawia wszystkie wyniki, gdy chcesz tylko znaleźć wynik z największą ilością.

+0

Jon, jak zrobiłbyś powyższe w C# linq? (z rs w db ....) –

+0

@NatePet: Masz na myśli wyrażenie zapytania? Który kawałek kodu? Zasadniczo nie ma obsługi wyrażeń zapytań dla 'FirstOrDefault()' (i oczywiście nie dla 'MaxBy'), więc musisz umieścić nawiasy okrągłe wokół wyrażenia zapytania, aby wywołać metody na końcu - a twoja projekcja byłaby nie -op. Zasadniczo byłoby to brzydsze. To * zdecydowanie * warto być wygodnym z obydwoma formami. –

Powiązane problemy