2010-12-30 36 views
6

Tôi có một lớp TaskWeekUI với định nghĩa này:LINQ- Max ở nơi mà điều kiện

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; } } 

và tôi đã viết truy vấn này:

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

là truy vấn này là đúng? Tôi có thể viết truy vấn của mình tốt hơn điều này không?

+0

xin lỗi, tôi đã chỉnh sửa và thêm truy vấn, tôi đã quên nó. – Shayan

+0

'p => p.PlanProgress! = Null' không được yêu cầu trong mệnh đề' Where' của bạn – fearofawhackplanet

+0

Tnx, nhưng tôi có thể viết truy vấn cho tối đa ở nơi điều kiện không? – Shayan

Trả lời

26

Tôi nghĩ rằng bạn muốn một mà PlanProgress > 0 có gần đây nhất EndDate.

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

+1, giải pháp rõ ràng đẹp mà không có bất kỳ ngoại lệ ngoại lệ nào được giới thiệu bằng cách sử dụng Max. – WileCau

+1

Tnx, tôi nghĩ đó là giải pháp đơn giản nhất. – Shayan

+2

Nó không phải là một sự lãng phí thời gian để sắp xếp toàn bộ danh sách chỉ để có được mục với 'EndDate' cao nhất? [This] (http://stackoverflow.com/a/1101979/1219414) có vẻ là một giải pháp tốt hơn. – Juan

3

Truy vấn này có vẻ đúng từ quan điểm của kết quả thu được.

Nhưng trong truy vấn bên trong của bạn tis.Where(p => p.PlanProgress != null && p.PlanProgress > 0).Max(w => w.EndDate) được tính cho mỗi phần tử trong bộ sưu tập với t.PlanProgress > 0

Vì vậy, một cách tốt hơn của nó để có được giá trị Max bên ngoài của một truy vấn như sau:

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

Đi p hơn nữa. PlanProgress! = Null là allways true vì p.PlanProgress không thuộc kiểu Nullable. Vì vậy, mã của chúng tôi trở nên như thế này:

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

Hoặc bạn có thể thay đổi định nghĩa về lớp học của bạn và làm cho p.PlanProgress loại 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, điều duy nhất tôi sẽ thay đổi là 'First' thành' FirstOrDefault' trừ khi anh ta có thể đảm bảo rằng sẽ luôn có một mục với 'PlanProgress> 0' –

+0

+1, nhưng tôi nghĩ 'bộ sưu tập .Max 'ném ngoại lệ nếu' bộ sưu tập 'trống, vì vậy có thể cần phải là một kiểm tra bổ sung trước khi đặt' tối đa '. Bộ sưu tập sẽ trống nếu tất cả PlanProgress <= 0. Vì có các kiểm tra cho PlanProgress> 0 Tôi cho rằng PlanProgress <= 0 là hợp pháp và một ngoại lệ có thể sẽ không được mong đợi. – WileCau

+0

Tnx cho câu trả lời của bạn. – Shayan

-1

Bạn không cần phải so sánh với PlanProgress null vì đôi là kiểu struct, nó không thể là null.

Nếu bạn muốn TaskWeekUI với Max EndDate và PlanProgress tích cực Bạn có thể thử mã này:

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

Nó sẽ kết thúc việc gán 'DateTime' thành' TaskWeekUI' – nan

+5

Không thể chuyển đổi hoàn toàn kiểu 'System.DateTime' sang 'TaskWeekUI' – Shayan