2010-12-30 11 views
6

Ho una classe TaskWeekUI con questa definizione:LINQ- Max in cui condizioni

public class TaskWeekUI { 
    public Guid TaskWeekId { get; set; } 
    public Guid TaskId { get; set; } 
    public Guid WeekId { get; set; } 
    public DateTime EndDate { get; set; } 
    public string PersianEndDate { get; set; } 
    public double PlanProgress { get; set; } 
    public double ActualProgress { get; set; } } 

e ho scritto questa query:

TaskWeekUI ti = tis.First(t => t.PlanProgress > 0 && t.EndDate == tis.Where(p => p.PlanProgress != null && p.PlanProgress > 0).Max(w => w.EndDate)); 

È questa query è vero? Posso scrivere la mia domanda meglio di questa?

+0

scusami, ho modificato e aggiunto query, l'ho dimenticato. – Shayan

+0

'p => p.PlanProgress! = Null' non è richiesto nella clausola' Where' – fearofawhackplanet

+0

Tnx, ma posso scrivere una query per max in condizione where? – Shayan

risposta

26

Penso che si desidera quello la cui PlanProgress > 0 ha una più recente EndDate.

TaskWeekUI ti = tis.Where(t => t.PlanProgress > 0) 
        .OrderByDescending(t => t.EndDate) 
        .FirstOrDefault(); 
+1

+1, bella soluzione chiara senza eccezioni estranee introdotte utilizzando Max. – WileCau

+1

Tnx, penso sia la soluzione migliore. – Shayan

+2

Non è una perdita di tempo per ordinare l'intera lista solo per ottenere l'oggetto con il più alto 'EndDate'? [Questo] (http://stackoverflow.com/a/1101979/1219414) sembra essere una soluzione migliore. – Juan

3

Questa query sembra essere corretta dal punto di vista del risultato ottenuto.

Ma nella vostra query interna tis.Where(p => p.PlanProgress != null && p.PlanProgress > 0).Max(w => w.EndDate) viene calcolato per ogni elemento della collezione con t.PlanProgress > 0

Quindi è un modo migliore per ottenere il valore massimo al di fuori di una query come segue:

var max = tis.Where(p => p.PlanProgress != null && p.PlanProgress > 0).Max(w => w.EndDate); 
tis.First(t => t.PlanProgress > 0 && t.EndDate == max); 

Andando oltre p. PlanProgress! = Null è sempre vero poiché p.PlanProgress non è di tipo Nullable. Così il nostro codice diventa in questo modo:

var max = tis.Where(p => p.PlanProgress > 0).Max(w => w.EndDate); 
    tis.First(t => t.PlanProgress > 0 && t.EndDate == max); 

Oppure si può cambiare la definizione della classe e fare p.PlanProgress di tipo Nullable:

public class TaskWeekUI { 
    public Guid TaskWeekId { get; set; } 
    public Guid TaskId { get; set; } 
    public Guid WeekId { get; set; } 
    public DateTime EndDate { get; set; } 
    public string PersianEndDate { get; set; } 
    public double? PlanProgress { get; set; } 
    public double ActualProgress { get; set; }  
} 

var max = tis.Where(p => p.PlanProgress.HasValue && p.PlanProgress.Value > 0).Max(w => w.EndDate); 
    tis.First(t => t.PlanProgress.HasValue && t.PlanProgress.Value > 0 && t.EndDate == max); 
+1

+1, l'unica cosa che cambierei è il 'Primo 'a un' PrimoOrDefault' a meno che non possa garantire che ci sarà sempre un elemento con 'PlanProgress> 0' –

+0

+1, ma penso' raccolta .Max 'genera un'eccezione se' raccolta 'è vuota, quindi probabilmente è necessario un controllo aggiuntivo prima di impostare' max '. La raccolta sarà vuota se tutto PlanProgress <= 0. Poiché ci sono controlli per PlanProgress> 0 presumo che PlanProgress <= 0 sia legale e probabilmente non ci si aspetterebbe un'eccezione. – WileCau

+0

Tnx per la tua risposta. – Shayan

-1

Non è necessario confrontare PlanProgress con null perché doppia è di tipo struct, non può essere nullo.

Se volete TaskWeekUI con Max EndDate e PlanProgress positivo Si può provare questo codice:

TaskWeekUI ti = tis.Where(t => t.PlanProgress > 0).Max(w => w.EndDate); 
+0

Si finirà per assegnare 'DateTime' a' TaskWeekUI' – nan

+5

Impossibile convertire implicitamente il tipo 'System.DateTime' in 'TaskWeekUI' – Shayan

Problemi correlati