Question

I'm starting to love Lambda expressions but I'm struggling to pass this wall:

public class CompanyWithEmployees {
    public CompanyWithEmployees() { }
    public Company CompanyInfo { get; set; }
    public List<Person> Employees { get; set; }
}

My search:

List<CompanyWithEmployees> companiesWithEmployees = ws.GetCompaniesWithEmployees();
CompanyWithEmployees ces = companiesWithEmployees
        .Find(x => x.Employees
        .Find(y => y.PersonID == person.PersonID));

So, I want to get the Object "CompanyWithEmployees" that have that Person (Employee) that I'm looking for, but I'm getting "Cannot implicit convert 'Person' To 'bool')" which is correct, but if I'm not passing the Person object, how can the first Find executes?

Was it helpful?

Solution

Because you want to check for existance, perhaps try:

ces = companiesWithEmployees
        .Find(x => x.Employees
        .Find(y => y.ParID == person.ParID) != null);

This will check for any Person with the same ParID; if you mean the same Person instance (reference), then Contains should suffice:

ces = companiesWithEmployees
        .Find(x => x.Employees.Contains(person));

OTHER TIPS

Find() returns the found object. Use Any() to just check whether the expression is true for any element.

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 returns only one object, x.Employees.Find(..) returns Person.

.Find expects boolean parameter(i.e. the result of conditions), that's why there's a compiler error that says Cannot implicit convert 'Person' To 'bool'

.Where can return multiple objects, hence can iterate through all list.

use a combination of .Where and .Any in your case.

the following code will illustrate the difference between .Where, .Find, and .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; }
}

That's because you haven't specified a legitimate Find expression for your top level Find.

I'll show it here:

ces = companiesWithEmployees
    .Find (x => x.Employees.Find(y => y.ParID == Person.ParID) /*condition is missing here*/);

So what is the condition for your initial find?

The easiest one would be

ces = companiesWithEmployees.FirstOrDefault(x => 
          x.Employees.Any(y => y.PersonID == person.ParID));

without any null check

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top