Linq с внутренним соединением и группировкой - PullRequest
1 голос
/ 29 мая 2020

Извините, это вопрос, который раздражает экспертов, но я искал похожие случаи и уверен, что они существуют, но я просто недостаточно хорош, чтобы понять, что применимо к моему сценарию.

У меня есть две таблицы, в которых есть отношение 1-n между MeasuresSet и Measure:

MeasuresSet {
   Id : Guid
   Date : DateTime
}

Measure {
   Id : Guid
   MeasuresSetId : Guid
   MeasureCategory : string
   Value : double
   VehicleName: string
}

MeasuresSet - это группа мер, которые были выполнены в один день, отсюда и дата.

Каждая строка в таблице Measure представляет собой конкретное c измерение, которое было выполнено на транспортном средстве. Например, это может быть MeasureCategory «давление в шинах» и соответствующее значение в фунтах на квадратный дюйм.

Другими словами: у каждого транспортного средства есть множество измерений одной и той же или разных категорий, выполненных в один и тот же день или в разные дни.

Я хочу иметь возможность написать запрос, который означает «Дайте мне все измерения, которые были выполнены для автомобиля« Автомобиль Майка », но сгруппируйте по MeasureCategory, чтобы я получил только самое последнее значение каждой MeasureCategory». Проблема в том, что дата хранится в MeasuresSet, не измерять. К сожалению, я теряюсь в объединении и группировке.

Я мог бы предположить, что это будет правильный запрос, но синтаксис неверен:

from MeasuresSet
join Measure
on MeasuresSet.Id equals Measure.MeasuresSetId  //your typical inner join
where VehicleName == "Mike's car"
group Measure by Measure.MeasureCategory into g
select new ResultType {
   MeasureCategory : g.Key,
   Date: g.OrderByDescending(data => data.Date).First().Date,
   Value: g.OrderByDescending(data => data.Date).First().Value,
};

1 Ответ

1 голос
/ 31 мая 2020
public class MeasuresSet
{
    public string Id { get; set; } //: Guid
    public DateTime Day { get; set; } //: DateTime
}

public class Measure
{
    public string Id { get; set; }//: Guid
    public string MeasuresSetId { get; set; }//: Guid
    public string MeasureCategory { get; set; } //: string
    public double Value { get; set; } //: double
    public string VehicleName { get; set; }//: string
}


var measureSets = new List<MeasuresSet>() {
new MeasuresSet() { Daisy = DateTime.Today, Id = "GUID-0" },
new MeasuresSet() { Daisy = DateTime.Today.AddDays(1), Id = "GUID-1" },
new MeasuresSet() { Daisy = DateTime.Today.AddDays(2), Id = "GUID-2" },
new MeasuresSet() { Daisy = DateTime.Today.AddDays(3), Id = "GUID-3" },
new MeasuresSet() { Daisy = DateTime.Today.AddDays(4), Id = "GUID-4" }};

var measures = new List<Measure>() {
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-0", Value = 10 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-0", Value = 11 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-0", Value = 12 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-1", Value = 20 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-1", Value = 21 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-1", Value = 22 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-2", Value = 30 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-2", Value = 31 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-2", Value = 32 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-3", Value = 40 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-3", Value = 41 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-3", Value = 42 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-4", Value = 50 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-4", Value = 51 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-4", Value = 52 },


new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-0", Value = 110 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-0", Value = 111 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-0", Value = 112 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-1", Value = 220 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-1", Value = 221 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-1", Value = 222 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-2", Value = 330 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-2", Value = 331 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-2", Value = 332 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-3", Value = 440 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-3", Value = 441 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-3", Value = 442 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "tyre pressure", MeasuresSetId = "GUID-4", Value = 550 },
//new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "engine", MeasuresSetId = "GUID-4", Value = 551 },
new Measure() { Id = Guid.NewGuid().ToString(), VehicleName = "NOT Mike's car", MeasureCategory = "air conditioner", MeasuresSetId = "GUID-4", Value = 552 }};


  var result = from set in (from measureSet in measureSets
                                  join measure in measures
                                       on measureSet.Id equals measure.MeasuresSetId
                                  select new
                                  {
                                      Day = measureSet.Day,
                                      ParentId = measureSet.Id,
                                      MeasureCategory = measure.MeasureCategory,
                                      Id = measure.Id,
                                      Value = measure.Value,
                                      VehicleName = measure.VehicleName
                                  })
                     where set.VehicleName == "Mike's car"
                     group set by set.MeasureCategory into g
                     select new
                     {
                         MeasureCategory = g.Key,
                         Day = g.Max(x => x.Day),
                         Value = g.First(x => x.Day == g.Max(y => y.Day)).Value
                     };

РЕЗУЛЬТАТЫ:

Mike's car
tyre pressure | 04/06/2020 00:00:00 | 50
engine | 04/06/2020 00:00:00 | 51
air conditioner | 04/06/2020 00:00:00 | 52


NOT Mike's car
tyre pressure | 02/06/2020 00:00:00 | 330
engine | 03/06/2020 00:00:00 | 441
air conditioner | 04/06/2020 00:00:00 | 552
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...