2010-11-22 2 views
2

D'abord, Thomas Levesque avait une bonne solution pour commander des champs dans une table liée où la relation ne peut pas toujours être là:Entity Framework 4 et LINQ: OrderBy un champ imbriqué dans une requête: factoriser mon code

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

J'ai besoin de faire la même chose. Ma racine globale est énorme:

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

Est-ce vraiment la façon de faire, ou est-il quelque chose de beaucoup plus facile à lire? Mon autre problème est que le myField imbriqué a une valeur "par défaut" correspondante dans la requête de niveau supérieur, également appelée par myField. L'idée était d'ordonner par la coalesce de ces deux champs (??).

Edit: Je pense que cela comprendrait la « valeur par défaut » du premier champ:

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

Comment pourrais-je réécris ce OrderBy être plus propre? Ce code échoue avec une erreur de type "Impossible de comparer les éléments de type 'System.Collections.Generic.IEnumerable`1'." Seuls les types primitifs (tels que Int32, String et Guid) et les types d'entité sont pris en charge. "

+2

Eh bien, peut-être vous devriez essayer de résoudre ce problème ailleurs. Êtes-vous sûr de devoir parcourir quatre relations? Ne pouvez-vous pas changer la base de données et/ou les mappages afin que vous obteniez les données dans un format plus approprié? –

+0

Je peux toujours ajouter une vue et/ou une procédure stockée, mais le résultat final est un objet JSON hiérarchique allant au client. Donc, je finirais par recréer une hiérarchie à partir d'un objet aplati. –

Répondre

2

Je pense que vous avez une mauvaise odeur de code qui se passe ici, mais en travaillant avec ce que vous avez je ne le ferais pas dans une requête LINQ comme ça. Juste pour des raisons de lisibilité, je ferais quelque chose comme

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

Et à l'intérieur de la classe de p

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