Après beaucoup de recherche Google et expérimentation de code, je suis souples sur un problème complexe C # Linq-Objects qui dans SQL serait facile à résoudre avec une paire de rangées de rangée () ... Partition par des fonctions et une sous-requête ou deux.
Voici, en mots, ce que j'essaie de faire en code - l'exigence sous-jacente élimine les documents en double à partir d'une liste: p>
STEP # 1 est facile (E.G. codePonet.blogspot.com/2009/01/group-by-in-linq.html), mais je me suis englé sur les marches n ° 2 et n ° 3. Je ne peux pas sembler construire une requête de linq en C # sans squiggle de rouge pour résoudre les trois étapes. P>
Anders Heilsberg's Post sur Ce fil est que je pense que la réponse aux étapes n ° 2 et n ° 3 ci-dessus si je pouvais obtenir la syntaxe droite. p>
Je préférerais éviter d'utiliser une variable locale externe pour effectuer le calcul de l'index, comme recommandé sur slodge.blogspot.com/2009/01/adding-row-number-utilisation-linq-to-objects .html, puisque cette solution se casse si la variable externe est modifiée. p>
de manière optimale, l'étape du groupe par titre pourrait être effectuée en premier, de sorte que les groupements "internes" (première par source pour calculer l'index, puis par index pour filtrer les doublons) peuvent fonctionner sur de petits nombres de Objets de chaque groupe "par titre", car le nombre de documents de chaque groupe de titres est généralement de moins de 100 ans. Je ne veux vraiment pas de solution N 2 sup>! P> Je pourrais certainement résoudre celui-ci avec des boucles de foresach imbriquées, mais cela semble être le genre de problème qui devrait être simple avec Linq. P> Des idées? P> P>
4 Réponses :
Pour être honnête, je suis assez confus avec votre question. Peut-être que si vous devriez expliquer ce que vous essayez de résoudre. Quoi qu'il en soit, je vais essayer de répondre à ce que j'ai compris.
1) Tout d'abord, je suppose que vous avez déjà une liste de documents regroupés par 2) pour obtenir un index dans chaque élément, vous pouvez utiliser l'extension 3) de ce que j'ai compris, la prochaine étape consisterait à regrouper le dernier résultat par titre code> +
sourceId code> . À des fins de test, j'ai une liste de code d'accès à la liste suivante: p>
SELECT CODE> méthode, passant une fonction de sélecteur de func. Comme ceci: p>
titre code>. Voici comment le faire: P>
foreach (var a in selectedFew) Console.WriteLine(a);
//The result will be:
//{ Doc = { Title = ABC, SourceId = 0 }, Index = 0 }
//{ Doc = { Title = 123, SourceId = 5 }, Index = 4 }
Bonjour Jpochi - La solution de Dahlby était une bonne. Désolé, je n'ai pas été capable de vous recontacter, c'était ma première question sur le débordement de la pile et je ne m'attendais jamais à obtenir 2 réponses en moins de 2 heures le dimanche! La prochaine fois, je vais vérifier plus vite! :-) Quoi qu'il en soit, merci pour l'aide.
Je pense que JPBOCHI a raté que vous souhaitez que vos groupements soient par paires de valeurs (titre + sourceID, puis index de titre +). Voici une solution LINQ (principalement) SOLUTION:
var selectedFew = from doc in docs group doc by doc.Title into titleGroup from docWithIndex in ( from doc in titleGroup group doc by doc.SourceId into idGroup from docIndex in idGroup.Select((d, i) => new { Doc = d, Index = i }) group docIndex by docIndex.Index into indexGroup select indexGroup.Aggregate((a,b) => (a.Doc.SourceId <= b.Doc.SourceId) ? a : b) ) select docWithIndex;
Hey Dahlbyk - C'est génial! Votre solution a l'air bien. Maintenant, je ne me sens pas si mal que d'être incapable de comprendre moi-même la première fois. J'ai découvert la surcharge Select-with-index mais ne pouvait pas comprendre comment l'obtenir dans une requête LINQ. Un code de ceinture en noir sur votre fin, merci pour l'aide et l'éducation dans ce qui est possible.
Diriez-vous que ce qui précède est la syntaxe méthode équivalente? P> P>
Oui, cela émet le même résultat (correct) que la syntaxe Linq-y de Dahlbyk ci-dessus. Bien que (voir la requête mise à jour de Dahlby), il est probablement plus efficace de grouper par le titre d'abord afin que tout tri / agrégation peut se produire sur des ensembles minuscules-- S'il y avait un milliard de documents, cela ferait une grande différence car vous ne seriez pas à charger tout d'entre eux dans la RAM à la fois. De plus, la plupart des titres n'auront pas du tout des doublons ... J'espère que le BCL a optimisé le tri et les opérations group-par des ensembles d'un membre. :-)
J'ai mis en œuvre une méthode d'extension. Il prend en charge plusieurs partitions par des champs ainsi que des conditions de commande multiples.
{ Title = "Title1", SourceId = 1 }, { Title = "Title2", SourceId = 14 }, { Title = "Title3", SourceId = 100 }