LINQ- Макс, где состояние - PullRequest
       13

LINQ- Макс, где состояние

9 голосов
/ 30 декабря 2010

У меня есть класс TaskWeekUI с таким определением:

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

и я написал этот запрос:

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

Является ли этот запрос верным? Могу ли я написать свой запрос лучше, чем этот?

Ответы [ 4 ]

34 голосов
/ 30 декабря 2010

Я думаю, вам нужен тот, у которого PlanProgress > 0 имеет самый последний EndDate.

TaskWeekUI ti = tis.Where(t => t.PlanProgress > 0)
                   .OrderByDescending(t => t.EndDate)
                   .FirstOrDefault();
4 голосов
/ 30 декабря 2010

Этот запрос представляется правильным с точки зрения полученного результата.

Но в вашем внутреннем запросе tis.Where(p => p.PlanProgress != null && p.PlanProgress > 0).Max(w => w.EndDate) вычисляется для каждого элемента в коллекции с t.PlanProgress > 0

Так что лучший способ получить максимальное значение вне запроса следующим образом:

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

Идем дальше p.PlanProgress! = Null всегда верно, поскольку p.PlanProgress не имеет типа Nullable Таким образом, наш код выглядит так:

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

Или вы можете изменить определение вашего класса и сделать p.PlanProgress типа 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);
0 голосов
/ 07 июля 2018
     var max_Query =
                   (from s in db.Songs
                    join bk in db.Albums on s.BookId equals addAlbumDetailsViewModel.BookId
                    select s.SongId).Max();
                            max_Query++;
0 голосов
/ 30 декабря 2010

Вам не нужно сравнивать PlanProgress со значением NULL, потому что double является структурным типом, оно не может быть NULL.

Если вам нужен TaskWeekUI с Max EndDate и положительным PlanProgress, вы можете попробовать этот код:

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