11
votes

Règles de pouce pour quand appeler TOLIST lors du retour des résultats LINQ

Je recherche des règles de pouce pour appeler Tolist / Toarray / mémozeall (RX) sur ienumerables , par opposition au retour de la requête elle-même lors du retour IEnumerable de quelque chose.

Souvent, je trouve qu'il est préférable de simplement renvoyer la requête et de laisser l'appelant décider si une liste est nécessaire ou non, mais parfois, elle peut se revenir et vous mordre à l'arrière en raison de la nature paresseuse de Linq.

Je veux collecter des directives telles que:

Appeler Tolist si:

  • Vous créez de nouveaux objets (par exemple, dans un SELECT)
  • Vous avez des effets secondaires dans votre requête

    Sinon, renvoyez la requête


1 commentaires

Vous devriez rarement (jamais?) Avoir des effets secondaires dans votre requête.


5 Réponses :


3
votes

retour Tolist si:

  • Vous ne voulez pas ou ne vous souciez pas d'évaluation de la requête paresseuse.

    EDIT:

    Aussi, retour Tolist si:

    • Vous utilisez une sorte de linq vers le cadre SQL (LLBLGEN, EF, etc.), et vous devez effectuer une opération sur la liste qui ne peut pas être traduite en SQL par le cadre.

1 commentaires

+1 pour la modification. Surtout si les opérations ultérieures entraîneraient une base de données à toucher plusieurs fois par la même requête. Utilisez le profileur SQL Server pour déterminer où utiliser tolist () .



1
votes

vous tolist () Lorsque vous souhaitez une liste d'objets pour votre résultat.


3 commentaires

+1: Je ne pense pas que cela puisse être meilleur que celui-ci comme une directive générale.


@Lasse: je fais. Cette réponse n'explique pas quand nous voudrions une liste .


Parce qu'il y a un million de cas d'utilisation dans lesquels vous souhaitez utiliser une liste et un million de cas d'utilisation (qui semblent bizarrement les mêmes) où vous ne voulez pas l'utiliser. C'est entièrement spécifique au scénario à portée de main. Quelle est la directive pour quand utiliser une variable? Quelle est la ligne directrice pour quand utiliser une chaîne? Vous ne pouvez pas vraiment créer une ligne directrice qui le dit. Maintenant, je suis d'accord, vous pouvez décrire les fonctionnalités d'une liste, puis dire "lorsque vous en avez besoin de l'une de ces informations, vous souhaitez utiliser une liste", mais il demande des directives sur renvoyant des données . Vous ne pouvez pas, car si vous souhaitez utiliser une liste ou non n'est pas à vous de décider.



2
votes

Utilisez TOLIST si vous devez exécuter des fonctions personnalisées sur les données renvoyées par LINQ vers SQL.


0 commentaires

24
votes

Tout d'abord, vous ne devriez jamais avoir d'effets secondaires dans une requête. C'est une pire pratique. Les requêtes doivent répondre à une question, ne pas produire un effet.

La réponse à votre question est la suivante: renvoyer une requête lorsque l'appelant s'attend à une requête; Renvoie une liste lorsque l'appelant attend une liste. Lorsque vous concevez votre méthode, décidez ce que l'appelant est plus susceptible de vouloir, implémenter cela, puis document .

Lorsque vous envisagez si l'appelant veut une requête ou une liste, réfléchissez aux différences entre les requêtes et les listes:

  • Les requêtes sont toujours à jour. Si les objets / bases de données / quoi que les requêtes de la requête contre changent de contenu changent, les résultats de la requête changeront si vous exécutez à nouveau la requête. Les listes ne changent pas leur contenu et donc les listes sont hors de la date . Si votre appelant nécessite les dernières données , donnez-leur une requête. S'ils ont besoin un instantané des données qu'ils peuvent inspecter à loisure , donnez-leur une liste.

  • Les requêtes sont potentiellement coûteuses à exécuter pour obtenir leurs résultats. Les listes sont bon marché pour obtenir leurs résultats. Si l'appelant est susceptible de vouloir interroger le résultat de plusieurs reprises et s'attend à obtenir les mêmes résultats à chaque fois, donnez-leur une liste.

  • construire une requête est rapide . Exécuter une requête pour construire une liste est lent . Une liste obtient toujours tous les résultats d'une requête. L'appelant voudra peut-être restreindre davantage la requête, par exemple, ne prenant que les dix premiers éléments. Si l'appelant ne veut pas ou n'a pas besoin de prendre les frais d'itération intégralement sur toute la requête, donnez-leur une requête; Ne faites pas cette décision en leur nom et donnez-leur une liste.

  • Les requêtes sont minuscule . Les listes sont gros . De nombreuses requêtes peuvent être itératées sur n articles dans O (1) espace; Une liste avec n articles prend o (n) espace. Si le jeu de résultats est énorme, le mettre dans une liste est probablement inefficace.

  • et ainsi de suite.

    Il n'y a pas de réponse facile. La réponse est la même que la réponse à tout autre problème de conception: Considérez tous les avantages et inconvénients de chaque solution possible dans le contexte de ce qui est probablement recherché par l'utilisateur de la fonctionnalité, puis choisissez une solution de compromis raisonnable .


0 commentaires

2
votes

Utiliser Tolist Avant de quitter le bloc à l'aide du bloc qui contient votre DataContext . .

Renvoie une requête lorsque l'appelant est probablement / obligé de fournir des critères de filtrage supplémentaires qui seront utilisés par des index pour réduire le nombre de lignes de résultat et / ou de la base de données IO.


0 commentaires