[C#/Linq] Combineren Linq resultaten meerdere Linq queries

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Ik ben aan het loopen over meedere directories, waarbij ik meerdere xml files uitlees en hier een linq query op doe. Als resultaat zou ik graag 1 result set hebben waarin alles staat vanuit meedere xml's. Hoe kan ik, het resultaat van de huidige linq query, toevoegen aan het resultaat van de vorige? (de declaratie van acbResult lijkt me niet buiten de for-loop gehaald te kunnen worden?)
Ik staar me een beetje suf er op... :?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
DirectoryInfo[] acbDirectories = new DirectoryInfo(_rundirectoy + @"\Report\Accountability").GetDirectories();
foreach (DirectoryInfo currentAcbDir in acbDirectories)
            {
                    XDocument xdoc = XDocument.Load(currentAcbDir.FullName + @"\_Accountabilty_Results.xml");
                    {
                        var acbResult = from element in xdoc.Descendants("TABLES")
                                        select new {TableName = element.Element("TABLENAME").Value,
                                                    Atrributes = Convert.ToInt32(element.Element("ACB_ATTRIBUTES").Value),
                                                    Correct = Convert.ToInt32(element.Element("CORRECT").Value),
                                                    NotCorrect = Convert.ToInt32(element.Element("NOTCORRECT").Value) };
                   }
          }

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • ZaPPZion
  • Registratie: Februari 2009
  • Laatst online: 28-08 12:46
misschien een list maken met meerdere results? dan kun je die weer samenvoegen na de loop?

Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Ja, dat zou ik wel willen, alleen van welke type moet die list dan zijn? Ik maak namelijk on-the-fly de objecten aan, die staan verder nergens als class gedefinieerd.

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

Als het goed is geeft een LINQ query een IENumerable<T> terug. Deze kan je mergen met een IENumerable<T> buiten je loop zoals een List<T>.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Sebazzz schreef op maandag 05 oktober 2009 @ 14:05:
Als het goed is geeft een LINQ query een IENumerable<T> terug. Deze kan je mergen met een IENumerable<T> buiten je loop zoals een List<T>.
Daar heb je helemaal gelijk in. Alleen geeft deze query een type terug dat on-the-fly wordt gegeneerd (met een new-statement op code regel 7). Dus wat moet ik van de T maken buiten de for loop (daar bestaat het type nog niet dat de linq query terug geeft)?

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Aangezien je inderdaad een anonymous type gebruikt heb je een probleem, aangezien je niet weet welk type dat is, en je kunt dus ook dat type niet gebruiken om een generieke List<T> te creeren.

De oplossing is dan ook meteen om gewoon geen anonymous type te gebruiken, maar gewoon je type ergens te definiëren.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Woy schreef op maandag 05 oktober 2009 @ 14:10:
Aangezien je inderdaad een anonymous type gebruikt heb je een probleem, aangezien je niet weet welk type dat is, en je kunt dus ook dat type niet gebruiken om een generieke List<T> te creeren.

De oplossing is dan ook meteen om gewoon geen anonymous type te gebruiken, maar gewoon je type ergens te definiëren.
Dat kan idd ook: ik maak mijn eigen class aan met 4 properties, en deze kan ik wel als List<MienEigenType> een list van maken en optellen etc.
Alleen dan is helaas wel het mooie voordeel van de anonymous types weg, dus ik had gehoopt dat er nog een andere oplossing was.

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Wallie schreef op maandag 05 oktober 2009 @ 14:13:
[...]

Dat kan idd ook: ik maak mijn eigen class aan met 4 properties, en deze kan ik wel als List<MienEigenType> een list van maken en optellen etc.
Alleen dan is helaas wel het mooie voordeel van de anonymous types weg, dus ik had gehoopt dat er nog een andere oplossing was.
Voor dat type kan je natuurlijk wel gewoon een private nested class gebruiken als je het type nergens buiten die class nodig hebt.

Ik zie eigenlijk het probleem van het definiëren van de class niet zo.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Woy schreef op maandag 05 oktober 2009 @ 14:19:
[...]

Voor dat type kan je natuurlijk wel gewoon een private nested class gebruiken als je het type nergens buiten die class nodig hebt.

Ik zie eigenlijk het probleem van het definiëren van de class niet zo.
Ach, d'r is ook geen probleem mee, alleen 't is wat meer werk: ik heb 3 linq queries waarij dit het geval is, dus dat zijn 3 extra classes (alleen maar omdat ik results wil combineren). Zal d'r ook niet echt van wakker liggen, maar had gehoopt dat het in 1 keer kon ;), aangezien ik, als ik 2 linq qeuries heb, en deze geven beide hetzelfde anonymous type terug, deze wel met een .Union zijn te combineren. De for loop gooit hier helaas roet bij in het eten.

[ Voor 13% gewijzigd door Wallie op 05-10-2009 14:25 ]

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • cfern
  • Registratie: Oktober 2009
  • Laatst online: 09:37
Zo, eens even onder m'n lurksteen vandaan kruipen.

Wat je misschien wel kunt gebruiken is het LINQ SelectMany statement.
Zeg je hebt een functie f(x) die een lijstje [y_1,..,y_n] teruggeeft. Met SelectMany kun je, als je meerdere waarden voor x hebt, de lijstjes f(x_1) t/m f(x_m) achter elkaar aan elkaar knopen tot één lange lijst.

De code in de openingspost zou dan zo iets worden:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
var acbResults =
    acbDirectories.SelectMany(
        currentAcbDir => 
        {
            var xdoc = XDocument.Load(currentAcbDir.FullName + @"\_Accountabilty_Results.xml");
            var acbResult = from element in xdoc.Descendants("TABLES")
                            select new {TableName = element.Element("TABLENAME").Value,
                                        Atrributes = Convert.ToInt32(element.Element("ACB_ATTRIBUTES").Value),
                                        Correct = Convert.ToInt32(element.Element("CORRECT").Value),
                                        NotCorrect = Convert.ToInt32(element.Element("NOTCORRECT").Value) };
            return acbResult;
        }
    );


Misschien heb je hier iets aan.

"I'd rather have a full bottle in front of me, than a full frontal lobotomy." (Tom Waits) | PoE


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
Nou, dat is eigenlijk best wel goed... heb het hier geïmplementeerd, en het werkt! _/-\o_

Dat is niet gênant, dat is professioneel.


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 13:21

Haan

dotnetter

Interessant, die SelectMany kende ik ook nog niet _o_ Ik heb een soort zelfde situatie laatst ook opgelost met een class met wat properties ipv anonymous types, maar ik zal nu eens kijken of dat ook anders kan.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 12:39

RayNbow

Kirika <3

cfern schreef op maandag 05 oktober 2009 @ 14:47:
Zo, eens even onder m'n lurksteen vandaan kruipen.

Wat je misschien wel kunt gebruiken is het LINQ SelectMany statement.
Zeg je hebt een functie f(x) die een lijstje [y_1,..,y_n] teruggeeft. Met SelectMany kun je, als je meerdere waarden voor x hebt, de lijstjes f(x_1) t/m f(x_m) achter elkaar aan elkaar knopen tot één lange lijst.

De code in de openingspost zou dan zo iets worden:
C#:
1
/* snip */
Je hoeft niet per se SelectMany direct te gebruiken, je kan ook de querysyntax gebruiken en dan vertaaldt de compiler het naar een SelectMany-aanroep:
C#:
1
2
3
4
5
6
7
8
9
10
11
var acbResults =
    from abcDir in acbDirectories
    let xdoc = XDocument.Load(Path.Combine(abcDir.FullName, "Accountabilty_Results.xml"))
    from element in xdoc.Descendants("TABLES")
    select new
    {
        TableName = element.Element("TABLENAME").Value,
        Atrributes = Convert.ToInt32(element.Element("ACB_ATTRIBUTES").Value),
        Correct = Convert.ToInt32(element.Element("CORRECT").Value),
        NotCorrect = Convert.ToInt32(element.Element("NOTCORRECT").Value)
    };


Let op de meerdere "from ... in ..." clauses. Dit is waar de compiler SelectMany gebruikt.

Edit:
Zie ook 7.15 Query expressions (.doc).

Edit 2:
Het is beter om Path.Combine te gebruiken dan handmatig een pad en een bestandsnaam aan elkaar te lijmen.

[ Voor 13% gewijzigd door RayNbow op 05-10-2009 16:31 ]

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • cfern
  • Registratie: Oktober 2009
  • Laatst online: 09:37
Je hoeft niet per se SelectMany direct te gebruiken, je kan ook de querysyntax gebruiken en dan vertaald de compiler het naar een SelectMany-aanroep:
Interessant. Die onthoud ik.

Ik gebruik zelf eigenlijk alleen de lambda syntax, maar zo'n meervoudige samenstelling ziet er wel een stuk overzichtelijker uit in query syntax.

"I'd rather have a full bottle in front of me, than a full frontal lobotomy." (Tom Waits) | PoE


Acties:
  • 0 Henk 'm!

  • Wallie
  • Registratie: Januari 2000
  • Laatst online: 09:14
RayNBow --> Die is ook intressant... :) Thank you! En thanks voor de Path.Combine ;)
hmmm, ik moet eens een Linq boek kopen, ben d'r nu een week mee bezig, maar d'r nog zoveel aan te leren..

[ Voor 9% gewijzigd door Wallie op 05-10-2009 17:03 ]

Dat is niet gênant, dat is professioneel.

Pagina: 1