JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=f512989eadd4add7db9b6dfcd5c8d588Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

LINQ Abfragen auf nested objects

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
abc_d
JLI Master Trainee


Alter: 34
Anmeldedatum: 27.01.2003
Beiträge: 615

Medaillen: Keine

BeitragVerfasst am: 21.04.2009, 10:02    Titel: LINQ Abfragen auf nested objects Antworten mit Zitat

Hallo,

ich habe folgendes Problem: Ich habe eine Klasse die eine Liste mit Children vom gleichen Typ beeinhaltet.

Code:

    public class ClassA
    {

        public ClassA()
        {
            ClassAList = new ObservableCollection<ClassA>();
        }

        public string Propstring { get; set; }
        public bool Propbool { get; set; }
        public ObservableCollection<ClassA> ClassAList { get; set; }

        public override string ToString()
        {
            string Childs = "";

            if (ClassAList.Count > 0)
                Childs += "\r\n";

            foreach (ClassA child in ClassAList)
                Childs += child.ToString() + "\r\n";

            return Propstring + " ClassA " + Propbool.ToString() + " " + Childs.TrimEnd();
        }

        public ObservableCollection<ClassA> Where(Func<ClassA, bool> pArgument, Func<ClassA, bool> pNegArgument)
        {
            ObservableCollection<ClassA> returnList = new ObservableCollection<ClassA>();

            //All with subelements
            var x = (from c in ClassAList.Where(pArgument)
                         select c);

            foreach(ClassA test in x)
            {
                ObservableCollection<ClassA> tempList = new ObservableCollection<ClassA>();

                //When argument
                foreach (ClassA a in (from c in test.Where(pArgument, pNegArgument) select c))
                {
                    tempList.Add(a);
                }

                test.ClassAList = tempList;
                returnList.Add(test);
            }

            //All without subelements
            var y = (from c in ClassAList.Where(pNegArgument)
                     select c);

            foreach (ClassA test in y)
            {
                test.ClassAList.Clear();
                returnList.Add(test);
            }

            return returnList;
        }
       
        public static ClassA CreateClassA()
        {
            ClassA classa = new ClassA();
            classa.Propbool = true;
            classa.Propstring = "Root - Speisen";

            //Pizzas
            ClassA classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot - pizza";
            classa.ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = false;
            classatemp.Propstring = "Root.Subroot.Subroot - pizzasalami";
            classa.ClassAList[0].ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = false;
            classatemp.Propstring = "Root.Subroot.Subroot - pizzafungi";
            classa.ClassAList[0].ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot.Subroot - pizzahawai";
            classa.ClassAList[0].ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot.Subroot.Subroot - mit käse";
            classa.ClassAList[0].ClassAList[0].ClassAList.Add(classatemp);

            //flury
            classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot - mcflury";
            classa.ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = false;
            classatemp.Propstring = "Root.Subroot.Subroot - mcflury schoko";
            classa.ClassAList[1].ClassAList.Add(classatemp);

            classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot.Subroot - mcflury vanille";
            classa.ClassAList[1].ClassAList.Add(classatemp);

            //salata
            classatemp = new ClassA();
            classatemp.Propbool = true;
            classatemp.Propstring = "Root.Subroot - salat";
            classa.ClassAList.Add(classatemp);

            return classa;           
        }
    }


Jetzt möchte ich mit LINQ über den ganzen Baum drübergehen. Das klappt zwar mit der folgenden Extended Method:

Code:

        static public IEnumerable<T> Descendants<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> DescendBy)
        {
            foreach (T value in source)
            {
                //if(Property.Method == true)
                yield return value;

                foreach (T child in DescendBy(value).Descendants<T>(DescendBy))
                {
                    yield return child;
                }
            }
        }


            var x = from c in classa.ClassAList.Descendants(c => c.ClassAList)
                    select c;


Allerdings muss ich das Zeug anschließend wieder in die Baumstruktur bekommen. Hat jemand eine Idee wie ich das am Besten mache, oder gibt es eine andere Möglichkeit LINQ Statements über den ganzen Baum anzuwenden?
_________________
http://mitglied.lycos.de/sarti/linuxisevil.gif Linux is evil - get the fact.

Never touch a running System - der Systemling
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AFE-GmdG
JLI MVP
JLI MVP


Alter: 44
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 21.04.2009, 15:03    Titel: Antworten mit Zitat

Ich habe noch nicht ganz herausgelesen, was diese Klasse darstellen soll.
Mit Linq kann man grundsätzlich alle arten von Auflistungen verarbeiten.
Um dir zu helfen müsste ich noch mal wissen, was die Klasse(n) sein soll(en), und wie sie miteinander in Verbindung stehen.

Um eine Rekursive Auflistung (also ein Baum mit beliebig vielen Ebenen) mit einer Linq-Abfrage zu bearbeiten benötigt man eine Hilfsfunktion, welche alle Objekte des Baumes als Liste des gleichen (Basis)Types zurückgeben. Oder man muss mehrere Linq-Aufrufe nutzen, die in sich selbst natürlich auch Rekursiv sein können.

Für Komplexe Aufgaben empfehle ich aber die 1. Variante.

Ich habe ähnliches bereits programmiert (Bäume, die rekursive Datenstrukturen darstellen) - aber ich habe dafür komplett eigene Implementierungen von IList<T>, ICollection<T>, IEnumerable<T> und IEnumerable verwendet.

MfG, AFE-GmdG
_________________
CPP:
float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum