2009-09-24 10 views
0

i ont une certaine Linq au code entité comme ceci:LINQ: Faire une commande par!

var tablearows = Context.TableB.Include("TableA").Where(c => c.TableBID == 1).Select(c => c.TableA).ToList(); 

Alors je retourne les résultats de TableA avec TableB.TableBID = 1

C'est tout bon

Maintenant, comment je peux trier TableA par une de ses colonnes? Il y a un plusieurs à plusieurs navires entre les deux tables

j'ai essayé de diverses manières sans regard, par exemple

var tablearows = Context.TableB.Include("TableA").Where(c => c.TableBID == 1).Select(c => c.TableA).OrderBy(p => p.ColumnToSort).ToList(); 

Dans le cas ci-dessus quand je tape « p. » Je n'ai pas accès aux colonnes de TableA, probablement parce qu'il est une collection d'objets tableA, pas une seule rangée

Répondre

3

Que diriez-vous à l'aide SelectMany au lieu de Select:

var tablearows = Context.TableB.Include("TableB") 
    .Where(c => c.TableBID == 1) 
    .SelectMany(c => c.TableA) 
    .OrderBy(p => p.ColumnToSort) 
    .ToList(); 

EDIT: Le expression ci-dessous rendement collection de l'élément de TableAs de la collection est une instance de collection TableA pas TableA instance- (c'est pourquoi vous ne pouvez pas obtenir les propriétés du TableA):

var tablearows = Context.TableB.Include("TableB") 
    .Where(c => c.TableBID == 1) 
    .Select(c => c.TableA); 

Si nous nous tournons la page Sélectionner pour SelectMany, nous obtenons le résultat comme une collection concaténés qui comprend des éléments:

var tablearows = Context.TableB.Include("TableB") 
    .Where(c => c.TableBID == 1) 
    .SelectMany(c => c.TableA); 
+0

Super, ça a marché. Alors puis-je demander exactement quelle est la différence et pourquoi cela a fonctionné? –

+1

@ Tom345: donnez-lui un upvote ou au moins accepter sa réponse – Hao

2

Bon, alors maintenant que je l'ai pris à bord qu'il ya une relation plusieurs à plusieurs, je pense Canavar est à droite - vous voulez un SelectMany.

Encore une fois, c'est plus facile de voir dans une expression de requête:

var tableARows = from rowB in Context.TableB.Include("TableA") 
       where rowB.TableBID == 1 
       from rowA in rowB.TableA 
       orderby rowA.ColumnToSort 
       select rowA; 

La raison pour laquelle il ne fonctionne pas est que vous avez un autre type de résultat. Auparavant, vous obtenez un type comme:

List<EntitySet<TableA>> 

(je ne sais pas exactement le type que je ne suis pas un gars LINQ à entités, mais ce serait quelque chose comme ça.)

maintenant nous avons aplani toutes les lignes de tableA dans une liste unique:

List<TableA> 

maintenant, vous ne pouvez pas commander une séquence de ensembles par une seule colonne dans une rangée - mais vous pouvez commander une séquence de lignes par une colonne. Donc, fondamentalement, votre intuition dans la question était juste lorsque vous avez dit «probablement parce que c'est une collection d'objets TableA, pas une seule rangée» - mais ce que vous entendez par «ça» n'était pas très clair.

Maintenant, cet aplatissement est-il réellement approprié pour vous? Cela signifie que vous ne savez plus quel B a contribué à un R particulier. Y a-t-il seulement un B impliqué ici, alors cela n'a pas d'importance?Si oui, il y a une autre option qui peut même effectuer mieux (je ne sais vraiment pas, mais vous pourriez vous regarder le SQL généré dans chaque cas et le profil il):

var tableARows = Context.TableB.Include("TableA") 
         .Where(b => b.TableBID == 1) 
         .Single() 
         .TableA.OrderBy(a => a.ColumnToSort) 
         .ToList(); 

Notez que cela échouer (ou au moins dans LINQ aux objets, je ne sais pas exactement ce qui se passera dans les entités) s'il n'est pas une ligne dans la table B avec un ID de 1. Fondamentalement, il sélectionne la seule rangée, puis sélectionne Tous associés à cette ligne, et les commande.

+0

Super, ça a marché. Alors puis-je demander exactement quelle est la différence et pourquoi cela a fonctionné? p.s. J'ai demandé à Canavar le même Q –

Questions connexes