T McKeown
T McKeown

Reputation: 12857

How do I combine these two linq queries into a single query?

How can I get this in to one query? What I want is the Person from the Company that matches the name of the person I'm searching for.

Currently I get the Company and then run basically the same search.

var existingCompany = bidInfo.Companies
        .FirstOrDefault( c=> c.CompanyDomain != null && 
                           c.CompanyDomain.People.FirstOrDefault( 
                                 p => p.Name == bidInfo.ArchitectPerson.Name ) 
                                        != null);
Person existingPerson=null;
if (existingCompany !=null)
{
     existingPerson = existingCompany.CompanyDomain.People.FirstOrDefault(p => p.Name == bidInfo.ArchitectPerson.Name);
}

Upvotes: 8

Views: 362

Answers (3)

AGB
AGB

Reputation: 2226

In order to find the Person from the Company that matches the name of the bidInfo.ArchitectPerson you're searching for, you will need to look at all the people in the companies associated with the bidInfo, and then find the person with the matching name.

This can be accomplished with the following:

var existingPerson = bidInfo.Companies
    .Where(c => c.CompanyDomain != null && c.CompanyDomain.People != null)
    .SelectMany(c => c.CompanyDomain.People)
    .FirstOrDefault(p => p.Name == bidInfo.ArchitectPerson.Name)


FirstOrDefault vs. SingleOrDefault:

Names are unlikely to be unique: one company could have more than one "John Smith" working for them; one bidInfo could contain several Companies, more than one of whom each employ a different "Jane Smith".

SingleOrDefault() will throw an exception if there is more than one element that matches the p.Name == bidInfo.ArchitectPerson.Name criterion.

So long as the "Smith cases" outlined above describe an acceptable state for your program, use FirstOrDefault().

Upvotes: 5

Enigmativity
Enigmativity

Reputation: 117175

If I understand correctly, you are trying to find the first company with a person that has the same name as the architect, and then return both.

If so, then I think this will work:

var query =
    from c in bidInfo.Companies
    from p in c.CompanyDomain.People
    where p.Name == bidInfo.ArchitectPerson.Name
    select new { c, p };

var first = query.FirstOrDefault();

Company existingCompany = first?.c;
Person existingPerson = first?.p;

Let me know if I've missed anything.

Upvotes: 2

Ronan Thibaudau
Ronan Thibaudau

Reputation: 3603

Assuming I understand what you're trying to do, you could do something like this:

var person = bidInfo.Companies
            .Where(c=>c.CompanyDomain != null)
            .SelectMany(c=>c.CompanyDomain.People)
            .SingleOrDefault(p=>p.Name == bidInfo.ArchitectPerson.Name);

Note that you're already not filtering on the company (you're just getting the first company that has someone with that name, what if there are multiples? If that's not possible then the company check is useless and you may as well do as I do and just select all people then filter on that instead of going inside of each company, checking if the person is there, then somehow going up and back down!)

Upvotes: 7

Related Questions