Lambda-Ausdrücke, wie innerhalb eines Objekts suchen?
Frage
Ich fange an Lambda-Ausdrücke zu lieben, aber ich bin zu kämpfen diese Mauer weitergeben müssen:
public class CompanyWithEmployees {
public CompanyWithEmployees() { }
public Company CompanyInfo { get; set; }
public List<Person> Employees { get; set; }
}
Meine Suche:
List<CompanyWithEmployees> companiesWithEmployees = ws.GetCompaniesWithEmployees();
CompanyWithEmployees ces = companiesWithEmployees
.Find(x => x.Employees
.Find(y => y.PersonID == person.PersonID));
Also, ich will das Objekt „CompanyWithEmployees“ erhalten, haben die Person (Mitarbeiter), die ich suche, aber ich bin immer „ kann nicht implizit konvertieren‚Person‘To‚Bool‘) “, das ist richtig, aber wenn ich nicht die Person Objekt übergeben bin, wie kann die erste ausführen finden?
Lösung
Weil Sie wollen für existance überprüfen, vielleicht versuchen:
ces = companiesWithEmployees
.Find(x => x.Employees
.Find(y => y.ParID == person.ParID) != null);
Dies wird mit dem gleichen Person
für jeden ParID
überprüfen; wenn Sie die gleiche Person
Instanz (Referenz) bedeutet, dann sollte Contains
genügen:
ces = companiesWithEmployees
.Find(x => x.Employees.Contains(person));
Andere Tipps
Find()
liefert das gefundene Objekt. Verwenden Sie Any()
nur zu prüfen, ob der Ausdruck für jedes Element wahr ist.
var ces = companiesWithEmployees
.Find(x => x.Employees
.Any(y => y.PersonID == person.PersonID));
ces = companiesWithEmployees
.First(x => x.Employees.Any(p=>p.PersonID == person.PersonID));
ces = companiesWithEmployees.Find( x => x.Employees.Find(...) );
.Find
kehrt nur ein Objekt, x.Employees.Find(..)
gibt Person
.
.Find
erwartet boolean Parameter (d. Das Ergebnis der Bedingungen), das ist, warum ein Compiler-Fehler es gibt, das sagt Cannot implicit convert 'Person' To 'bool'
.Where
können mehrere Objekte zurückgeben, daher können alle durchlaufen Liste.
verwendet eine Kombination aus .Where
und .Any
in Ihrem Fall.
Mit dem folgenden Code wird veranschaulicht den Unterschied zwischen .Where
, .Find
und .Any
:
public partial class Form2 : Form {
public Form2() {
InitializeComponent();
var companiesWithEmployees = new List<CompanyWithEmployees>() {
new CompanyWithEmployees {
CompanyInfo = new Company { CompanyName = "Buen" },
Employees = new List<Person>() {
new Person { PersonID = 1976, PersonName = "Michael" },
new Person { PersonID = 1982, PersonName = "Mark" },
new Person { PersonID = 1985, PersonName = "Matthew" },
new Person { PersonID = 1988, PersonName = "Morris" }
}
},
new CompanyWithEmployees {
CompanyInfo = new Company { CompanyName = "Muhlach" },
Employees = new List<Person>() {
new Person { PersonID = 1969, PersonName = "Aga" },
new Person { PersonID = 1971, PersonName = "Nino" },
new Person { PersonID = 1996, PersonName = "Mark" }
}
},
new CompanyWithEmployees {
CompanyInfo = new Company { CompanyName = "Eigenmann" },
Employees = new List<Person>() {
new Person { PersonID = 1956, PersonName = "Michael" },
new Person { PersonID = 1999, PersonName = "Gabby" }
}
}
};
// just explicitly declared the types (instead of var) so the intent is more obvious
IEnumerable<CompanyWithEmployees> whereAreMichaels = companiesWithEmployees
.Where(cx => cx.Employees.Any(px => px.PersonName == "Michael"));
string michaelsCompanies = string.Join(", ", whereAreMichaels
.Select(cx => cx.CompanyInfo.CompanyName).ToArray());
MessageBox.Show("Company(s) with employee Michael : " + michaelsCompanies);
Person findAga = companiesWithEmployees
.Find(company => company.CompanyInfo.CompanyName == "Muhlach")
.Employees.Find(person => person.PersonName == "Aga");
if (findAga != null)
MessageBox.Show("Aga's ID : " + findAga.PersonID.ToString());
}
}
class CompanyWithEmployees {
public Company CompanyInfo { get; set; }
public List<Person> Employees { get; set; }
}
class Company {
public string CompanyName { get; set; }
}
class Person {
public int PersonID { get; set; }
public string PersonName { get; set; }
}
Das ist, weil Sie nicht einen berechtigten finden Ausdruck für Ihre Top-Level-Suche angegeben haben.
Ich werde es zeigen sich hier:
ces = companiesWithEmployees
.Find (x => x.Employees.Find(y => y.ParID == Person.ParID) /*condition is missing here*/);
Was ist also die Bedingung für Ihre erste finden?
Das einfachste wäre,
ces = companiesWithEmployees.FirstOrDefault(x =>
x.Employees.Any(y => y.PersonID == person.ParID));
ohne NULL-Prüfung