LINQ, выберите только с первым элементом дочернего элемента - PullRequest
2 голосов
/ 02 августа 2011

С LINQ, как сделать выбор и вернуть только первый связанный дочерний элемент?

У меня есть:

[table: Report]
    GeneratedDate
    PerformanceMetric  1 -----> N [table PerformanceMetric]
    Bios                              Timestamp
    ...                               X
                                      Y 
                                      ..... (there is a good dozen other fields)

В настоящее время я делаю:

 Report = _ctx.Reports.SingleorDefault(rpt => rpt.bios == mySerial);

Возвращает отчет со всеми связанными PerformanceMetric. Я хотел бы получить только первое возвращение PerformanceMetric.

Предоставляет ли LINQ встроенный способ сделать это?

РЕДАКТИРОВАТЬ: На самом деле я ищу отчет, но PerformanceMetric должен содержать только первый элемент. (Report.PerformanceMetrics.Count <= 1) извините за непонятность .. </p>

Ответы [ 2 ]

3 голосов
/ 02 августа 2011

Трудно точно определить полную структуру, основанную на вашем XML, но что-то вроде:

var firstMetric = _ctx.Reports
    .Where(rpt => rpt.bios == mySerial)
    .Select(rpt => rpt.PerformanceMetrics) // assuming name here...
    .FirstOrDefault();

Возвращает первую метрику производительности отчета, соответствующую mySerial, или значение по умолчанию (пустое для классов), если гдеВ предложении не найдены отчеты или отсутствуют показатели производительности.

Обновление: на основе обновления в вопросе, вы хотите что-то другое.Вам нужен отчет, но только с одной метрикой производительности.Это включает в себя изменение оригинального отчета (не уверенного во всех участниках), что может быть довольно проблематично, потому что вы не хотите манипулировать своими исходными данными в LINQ.

Таким образом, у вас есть два варианта:

  1. Вы можете создать новый экземпляр отчета и скопировать все свойства и только одну метрику.
  2. Вы можете создать анонимныйвведите вместе с отчетом и свойством.

Я бы предпочел # 2, поскольку возврат измененного отчета может привести к путанице.Таким образом, вы можете сделать:

var firstMetric = _ctx.Reports
    .Where(rpt => rpt.bios == mySerial)
    .Select(new { Report = rpt, Metric = rpt.PerformanceMetrics.FirstOrDefault() })
    .FirstOrDefault();

Это отсканирует Отчеты на предмет, где bios == mySerial, создаст новый анонимный тип с элементом Report == для исходного отчета и элементом Metric ==первая метрика в списке отчетов.

Если метрик не существует, но отчет существует, вы получите анонимный тип с Report = your report и Metric = null.Если ни один отчет не соответствует условию, возвращает ноль.

Если вы действительно хотите # 1, вы можете сделать это:

var firstMetric = _ctx.Reports
    .Where(rpt => rpt.bios == mySerial)
    .Select(new Report 
        { 
            PerformanceMetrics = rpt.PerformanceMetrics.Take(1),
            // copy all other Report fields here...
        })
    .FirstOrDefault();
2 голосов
/ 02 августа 2011

Вы ищете что-то подобное?

var reportMetric = (from r in _ctx.Reports select r.PerformanceMetric where r.Bios == mySerial).FirstOrDefault();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...