Question

I have multiple Person objects that each may contain 0 or more Email objects. I need to perform a search for a Person against a Collections of Persons and find records where an email addresses contained in Person also exists in any of the in the collection of Person records. I can then take action to merge these records

Summarised class structure below:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Email> Emails { get; set; }
}


public class Email
{
    public string Label { get; set; }
    public string Address{ get; set; }
    public bool IsPrimary { get; set; }
}

I need to find a List and find people with the same email address. However, I cant figure out how to construct a LINQ query that matches a Person and loops through a Collection of Person obejcts and compares email addresses?

Ideally this would be a lambda, but would love to know the step by step process for creating it.

Was it helpful?

Solution

You can project people to sequence of Email-Person pairs and group these sequence by email address. In this case each group will have people which share same email address (key of group):

people.SelectMany(p => p.Emails.Select(e => new { e.Address, Person = p }))
      .GroupBy(x => x.Address)
      .Select(g => new { Address = g.Key, People = g.Select(x => x.Person) })

Query syntax:

from p in people
from e in p.Emails
select new { e.Address, Person = p } into x
group x by x.Address into g
select new {
   Address = g.Key,
   People = g.Select(x => x.Person)
}

NOTE: If you need whole email to be unique, then override Equals and GetHashCode methods of Email in order to compare instances of this class by values of its fields instead of by reference (or make sure you are share same instances of email between different people).

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