2

First, Thomas Levesque had a good solution for ordering fields in a related table where the relation may not always be there:

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

I need to do the same thing. My aggregate root is enormous:

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

Is this really the way to do this, or is there something much easier to read? My other problem is that the nested myField has a matching "default" value sitting in the top level Query, also named by myField. The idea was to Order by the coalesce of these two fields (??).

Edit: I think this would include the "default value" from the first field:

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

How could I rewrite this OrderBy to be cleaner? This code fails with an error of "Cannot compare elements of type 'System.Collections.Generic.IEnumerable`1'. Only primitive types (such as Int32, String, and Guid) and entity types are supported."

Community
  • 1
  • 1
Zachary Scott
  • 20,968
  • 35
  • 123
  • 205
  • 2
    Well, maybe you should be trying to solve this problem somewhere else. Are you sure you need to navigate through four relations? Can't you change the database and/or mappings so you get the data in a more apropriate format? – R. Martinho Fernandes Nov 22 '10 at 05:18
  • I can always add a view and/or stored procedure, but the end result is a hierarchical JSON object going to the client. So I would end up recreating a hierarchy from a flattened object. – Zachary Scott Nov 22 '10 at 05:25

1 Answers1

2

I think you have a pretty nasty code smell going on here, but working with what you have got I wouldn't handle this in a LINQ query like that. Just for the sake of readability I'd do something like

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

And inside of p's class

private bool HasValidFields
{
  get
  {
    return p.Seconds != null &&
           p.Seconds.FirstOrDefault() != null &&
           .... ;
  }
}
Martin Doms
  • 8,598
  • 11
  • 43
  • 60