| 

.NET C# Java Javascript Exception

1
Hallo,

wir haben zwei verschachtelte Listen, vergleichbar:
List<Lehrer> enthält n Elemente von List<Schueler>.

Nun möchten wir eine (LINQ) Filterung machen. Es sollen diejenigen Lehrer übrig bleiben, die einen Schüler mit dem Namen "Fritz" in ihrer Schüler-/Unterliste haben. Allerdings soll in der Ergebnisliste der Lehrer auch nur noch die Schüler Items enthalten sein, die dem Kriterium entsprochen haben (Name = Fritz).

Es sind sozusagen zwei Filterungen in einem Rutsch.

Wie geht das...?
News:
24.07.2012
Magier77 238 1 6
3 Antworten
0
Hallo,

gibts eine Beziehung von Schüler zu Lehrer? Wenn ja filtere umgekehrt, in etwa so:
var query = schüler
.Where(s => s.Name == "Fritz")
.Select(s => new
{
Lehrer = s.Lehrer,
Schüler = s.Name
});


Wenn nicht, schau dir mal SelectMany an.

mfG Gü
24.07.2012
gfoidl 9,4k 3 5
Bei einer solchen Struktur würde das nicht gehen:

internal class Lehrer : Person {
public List<Schueler> schueler = new List<Schueler>();
}

internal class Schueler : Person {}

internal abstract class Person {
public int id;
public string name;
}

Und auch SelectMany würde dann nicht helfen.
Floyd 24.07.2012
Ich hab noch ein wenig mit Custome-Linq-Extensions rum gespielt aber mir ist leider auch damit keine Lösung eingefallen :/
Floyd 24.07.2012
Die genaue Struktur ist diese:
public class Mandant
//Properties:
public int Nr { get; set; }
public List<Buchung> Buchungen { get; set; }

public class Buchung
//Verlegenheits-Property:
public int MandantNr { get; set; }

public class Transaktion : Buchung

public class Forderung : Buchung
Magier77 24.07.2012
Sorry, hier ist nun der Mandant der "Lehrer" und jede Buchung ein "Schüler" um im Bild zu bleiben.
Magier77 24.07.2012
0
Hi Gü.

Eine "Beziehung" nicht direkt. Aber um das Problem zu lösen hatten wir extra ein Feld "LehrerNr" in die Schüler Objekte eingefügt, obwohl eigentlich gar nicht benötigt. Geholfen hat's bisher nicht...

SelectMany hatten wir auch schon zwischen. Hat leider nicht geklappt.

Was ich vergessen hatte zu erwähnen: Wir würden gern als Endergebnis die Liste der gefilterten LEHRER (mit den gefilterten Schülern im Bauch natürlich) bekommen. Mit: new {Lehrer, Schüler} wird das so aber nichts, oder?
24.07.2012
Magier77 238 1 6
0
Nach etwas weiter rumexperimentieren und merken, dass ich den Wald vor lauter Bäumen nicht sehe, ist mir folgenden Lösung eingefallen:

internal class Program {
private static void Main(string[] args) {

Schueler s1 = new Schueler() {id = 1001, name = "Fritz"};
Schueler s2 = new Schueler() {id = 1002, name = "Maria"};
Schueler s3 = new Schueler() {id = 1003, name = "Klaus"};

List<Lehrer> ll = new List<Lehrer>();
ll.Add(new Lehrer() {id = 1, name = "Lehrer 1", schueler = new List<Schueler>() {s1, s2, s3}});
ll.Add(new Lehrer() {id = 2, name = "Lehrer 2", schueler = new List<Schueler>() {s1, s3}});
ll.Add(new Lehrer() {id = 3, name = "Lehrer 3", schueler = new List<Schueler>() {s2, s3}});

var x = ll.Select(l => {
Lehrer nl = l;
nl.schueler = l.schueler.Where(s => s.name == "Fritz");
return !nl.schueler.Any() ? null : nl;
});

foreach (Lehrer x1 in x) {
Console.WriteLine(x1.name);
foreach (Schueler schueler in x1.schueler) {
Console.WriteLine(" " + schueler.name);
}
}
Console.WriteLine("---");
Console.ReadKey();
}

}
internal class Lehrer : Person {
public IEnumerable<Schueler> schueler = new List<Schueler>();
}

internal class Schueler : Person {}

internal abstract class Person {
public int id;
public string name;
}
24.07.2012
Floyd 14,6k 3 9
Floyd 14,6k 3 9
Dieser Ausdruck erscheint mir noch etwas besser:

var lehrer = from l in ll
let schueler = l.schueler
where schueler.Where(s => s.name == (searchedName)).Distinct().Count() > 0
select (l);
– Gast 25.07.2012


var lehrer = from l in ll
let schueler = l.schueler.Where(s => s.name == (searchedName)).Select(s => s).Distinct()
where schueler.Count() > 0
select new { LehrerName = l.name, Schueler = schueler.FirstOrDefault() };
– Gast 25.07.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH