Entity Framework 4 и Linq: OrderBy поле, вложенное в Query: рефакторинг моего кода - PullRequest
2 голосов
/ 22 ноября 2010

Во-первых, У Томаса Левеска было хорошее решение для упорядочения полей в связанной таблице, где не всегда может быть связь:

userQuery = userQuery.OrderBy(u => 
    (u.Department != null) ? u.Department.Name : String.Empty);

Мне нужно сделать то же самое.Мой совокупный корень огромен:

myQuery = myQuery.OrderBy(p =>
  (p.Seconds == null
    ? 0
    : p.Seconds.FirstOrDefault() == null
      ? 0
      : p.Seconds.First().Thirds == null
        ? 0
        : p.Seconds.First().Thirds.FirstOrDefault() == null
          ? 0
          : p.Seconds.First().Thirds.First().Forths == null
            ? 0
            : p.Seconds.First().Thirds.First().Forths.FirstOrDefault() == null
              ? 0
              : p.Seconds.First().Thirds.First().Forths.First().myField));

Это действительно способ сделать это, или есть что-то намного легче читать?Другая моя проблема заключается в том, что вложенный myField имеет соответствующее значение «по умолчанию», находящееся в запросе верхнего уровня, также называемом myField.Идея заключалась в том, чтобы упорядочить путем объединения этих двух полей (??).

Редактировать: Я думаю, что это будет включать в себя "значение по умолчанию" из первого поля:

myQuery = myQuery.OrderBy(p =>
  (p.Seconds == null
    ? p.myDefaultField // Used to be zero
    : p.Seconds.FirstOrDefault() == null
      ? p.myDefaultField
      : p.Seconds.First().Thirds == null
        ? p.myDefaultField
        : p.Seconds.First().Thirds.FirstOrDefault() == null
          ? p.myDefaultField
          : p.Seconds.First().Thirds.First().Forths == null
            ? p.myDefaultField
            : p.Seconds.First().Thirds.First().Forths.FirstOrDefault() == null
              ? p.myDefaultField
              : p.Seconds.First().Thirds.First().Forths.First().myField));

Как мне переписать этот OrderBy, чтобы он был чище? Этот код завершается с ошибкой «Невозможно сравнить элементы типа System.Collections.Generic.IEnumerable`1 '. Только примитивные типы (такие как Int32, String,и Guid) и типы объектов поддерживаются. "

1 Ответ

2 голосов
/ 22 ноября 2010

Я думаю, что у вас здесь довольно неприятный запах кода, но работая с тем, что у вас есть, я бы не справился с этим в запросе LINQ, подобном этому.Просто для удобства чтения я бы сделал что-то вроде

myQuery = myQuery.OrderBy(p =>
  (p.HasValidFields()
    ? p.Seconds.First().Thirds.First().Forths.First().myField
    : p.myDefaultField
  ));

И внутри класса p

private bool HasValidFields
{
  get
  {
    return p.Seconds != null &&
           p.Seconds.FirstOrDefault() != null &&
           .... ;
  }
}
...