Je n'ai pas les connaissances pour savoir comment ça se passe effectivement, mais par compte je peux répondre aux questions de façon logique 
Et les objets qui ne satisfont pas le test, ils sont où ? Il sont bien en mémoire. Il a bien fallu les charger pour que tu fasse to
Pour ça, je pense exactement comme Tomlev, la référence de l'objet "importé" serait réaffectée à l'objet suivant, et donc un seul objet à la fois en Ram (plus la liste des résultats, évidemment).
Si t'as table contient 100 lignes ça veut dire que tu vas faire 100 requêtes à la suite pour récupérer un seul objet à la fois ?
Une seule requête ramenant les 100 lignes d'un coup est plus optimisée.
Ben oui, mais ce serait justement l'avantage d'avoir les deux méthodes : 100 lignes? je fais un "tolist". 1 million de lignes à parcourir? je fais un foreach.
Si ta technique fonctionnait, ça reviendrait au même en ram. Tu aurais au final autant d'objets d'un coté comme de l'autre. Charger 100 lignes une a une contre charger 100 lignes d'un coup, ça fait 100 objets à la fin.
Je suis de nouveau du même avis que Tomlev, si j'ai 100.000 objets à parcourir et que mon test doit en ramener 100 : Avec le tolist j'ai 100.000 objets en Ram + les 100 du résultat. Avec le foreach j'aurais 1 objet + les 100 du résultat. Il n'y a pas photo.
Pourquoi "pour juste un élément" ? Là tu ne travailles pas sur un seul élément étant donné que tu fais un foreach. Tu veux donc travailler sur TOUS les éléments de base.table.
Tu dis que tu veux tous les éléments de base.table, linq te les ramène...
Ce que je veux dire, c'est que si je veux par exemple exécuter ce genre de truc :
Ramener le premier élément de la table qui corresponde à ma requête "EstDansLeTableau", et que ma table contienne des dizaines de milliers d'enregistrement, je risque de tomber à court de RAm alors que je n'ai besoin que d'un seul élément.
Ca revient à dire que linq ne fait rien d'autre d'utile que de ramener toute la table de la base en Ram, et je connais peu de programmeurs qui vont ramener une Bdd en Ram pour y faire des recherches.
A la limite, c'était plus efficace ce que je faisais avant de connaître linq et C# : je créais un fichier à accès direct et je me balladais dedans en y faisant tous les tests possibles et imaginables sans limite aucune et sans rien importer d'autre que l'objet en cours de test.
Le truc c'est que dans ton cas tu n'as pas besoin de te poser la question.
Ben si, parce que je n'ai pas évidemment donné le programme entier, je n'ai mis qu'un exemple. J'ai d'autres tests à faire du même genre.
Tu veux récupérer tous les clients donc les NumClient ne sont pas contenus dans tabls1 et tabl2. C'est bien ça ?
Cette requêtes est tout à fait traductible en SQL. Ta méthode EstDansLeTableau ne l'ait pas (comme on te l'a expliqué au début) mais la requête en elle même si. C'est un simple SELECT * FROM CLIENT WHERE NUMCLIENT NOT IN ('146', '1258', '8756').
En Linq ça donne ça:
..
PS: je n'ai pas testé le code
C'est une réponse constructive, malheureusement ça ne fonctionne pas d'avantage. Voici le message d'erreur retourné à l'exécution :
LINQ to Entities ne reconnaît pas la méthode « Boolean Contains[String](System.Collections.Generic.IEnumerable`1[System.String], System.String) », et cette dernière ne peut pas être traduite en expression de magasin.
PS2: je ne trouve pas très top de stocker des long dans un tableau de string
Je comprends parfaitement, mais de nouveau ce n'est qu'un bout de code. Ce tableau provient du split d'une chaîne de caractères qui peut être une combinaison d'introduction manuelle de l'utilisateur et d'introduction automatique via des choix de listes etc. Au final, l'utilsateur obtient une chaîne du type : "120,125,201,305,466"
qui, une fois splittée donne le tableau dont on parle.
Si tu fais un foreach sur une requête qui renvoie 1 million de lignes, il ne va pas créer 1 million d'objets avant de commencer à les renvoyer à l'énumérateur, sinon ce serait impossible de faire des traitements de masse à moins d'avoir une RAM énorme
C'est bien ça qui m'inquiète, d'où ma question si la requête est unique : je procède comment pour obliger la base à rapatrier un élément à la fois? J'opère "manuellement" dans une boucle de requête avec recherches sur la clé? Ca, par contre, ça oblige le moteur à rechercher dans la base pour chaque itération.
Parce que si ça fonctionne comme ça, je n'ai en fait qu'une façon de procéder :
1) Je fais tous mes tests transformables en sql, mais je ne rappatrie qu'un tableau de clé d'index.
2) Je fais un foreach dans le tableau de clé, en commençant par une recherche sur le numéro de clé puis mes tests sur l'élément rapatrié.
Sinon, j'ai jeté un oeil sur la vidéo dlinq venant de chez Microsoft, avec un exemple de requête suivie de "foreach".
Pierre Lagarde dit déjà, ce qui est amusant : "Quand est-ce que la requete est exécutée? en fait c'est très clair..."
puis il dit :
"Quand le foreach commence à sa faire sa boucle, dans un ienumerator avant de parcourir le premier élément, il génère sa requête."
Jusque là, c'est clair et conforterait la vision "retour en ram".
Mais il précise :
"Ensuite, il fait une boucle while qui contient un yield return" qui renvoie un reader"
"Il exécute la requête dans un ienumarator, il récupère le curseur sur la requête, il fait son while jusqu'à ce qu'il arrive au bout de son reader, et pour chacun des éléments il fait un yield return, et il construit l'objet qu'il renvoie dans le select."
Il ajoute en montrant la requête précédent le foreach : "Ici on est en train de construire le reader, et on en ressort avec le yield".
Ce qui conforterait l'option "un par un", non?
C'est sensé être très clair, mais on aurait pu exprimer ça pour que ça ne puisse pas être compris de façon ambigüe.
Où est la réalité?
Claude
Partager