1111lt
1111lt

Reputation: 35

Linq - group each class

I need help removing duplicates form the emailaddresses list. I need to add the code to group emailaddresses within the emailaddresses class. Sql is returning duplicate email addresses because of the different telephone numbers. Any suggestions? Thanks.

Here is my code: 1. Classes

public class Student
{
    public string StudentId { get; set; }
    public string Gender { get; set; }  
    public List<EmailAddresses> emailAddresses { get; set; }
}

public class EmailAddresses
{
    public string EmailAddress { get; set; }    
}

2. Data coming from sql query

StudentId   EmailAddresses  IsPreferred Number  TelephoneType                                                                                               
123456789   [email protected]   FALSE   5556565 Present Evening Phone                                                                                               
123456789   [email protected]   FALSE   8885566 Permanent Day Phone                                                                                             
123456789   [email protected]    TRUE    5556565 Present Evening Phone                                                                                               
123456789   [email protected]    TRUE    8885566 Permanent Day Phone                                                                                             
456789123   [email protected]    TRUE    7513150 Business Day Phone                                                                                              
456789123   [email protected]   TRUE    4123300 Present Day Phone                                                                                               
456789123   [email protected]   FALSE   4123300 Present Day Phone

3. Code

public List<Student> GetStudentData()
{
    List<Student> dataStudent;
    using (IDbConnection connection = RepositoryHelper.OpenConnection())
    {
        dataStudent = connection.Query<dynamic>(
            "mystoredprocedure", 
            commandType: CommandType.StoredProcedure)
                .GroupBy(x => x.StudentId)
                .Select(x => new Student 
                    { 
                        StudentId = x.First().StudentId, 
                        Gender = x.First().Gender,
                        emailAddresses = x.Select(ea => new EmailAddresses 
                            { 
                                EmailAddress = ea.emailAddresses 
                            }).ToList()
                    }).ToList();

        return dataStudent;
    }
}

Upvotes: 2

Views: 116

Answers (2)

David L
David L

Reputation: 33853

While it would be preferable to filter out duplicates before returning, it also increases the complexity of your code. If your result set is small, the memory and cpu overhead of filtering after you've returned the data may be suffer-able to easily and clearly get the results that you need. You can use a custom IEqualityComparer to check for distinct results and create a new emailAddresses list on each Student record that contains distinct email addresses.

public List<Student> GetStudentData()
{
    List<Student> dataStudent;
    using (IDbConnection connection = RepositoryHelper.OpenConnection())
    {
        dataStudent = connection.Query<dynamic>(
            "mystoredprocedure", 
            commandType: CommandType.StoredProcedure)
                .GroupBy(x => x.StudentId)
                .Select(x => new Student 
                    { 
                        StudentId = x.First().StudentId, 
                        Gender = x.First().Gender,
                        emailAddresses = x.Select(ea => new EmailAddresses 
                            { 
                                EmailAddress = ea.emailAddresses 
                            }).ToList()
                    }).ToList();

        dataStudent.ForEach(x => x.emailAddresses = x.emailAddresses
            .Distinct(new StudentEmailEqualityComparer()).ToList());

        return dataStudent;
    }
}

public class StudentEmailEqualityComparer : IEqualityComparer<EmailAddresses>
{

    public bool Equals(EmailAddresses x, EmailAddresses y)
    {
        return x.EmailAddress.Equals(y.EmailAddress);
    }

    public int GetHashCode(EmailAddresses obj)
    {
        return obj.EmailAddress.GetHashCode();
    }
}

Upvotes: 1

Pranay Rana
Pranay Rana

Reputation: 176946

If i get you correct you need to get distinct values for that you can do like this

 List<Product> list = products
                   .GroupBy(a => a.Code )
                   .Select(g => g.First())
                   .ToList();

or

Create comperare and than try to find out distinct object

article for full code : DistinctBy in Linq (Find Distinct object by Property)

    class ProductComparare : IEqualityComparer<product>
    {
        private Func<Product, object> _funcDistinct;
        public ProductComparare(Func<Product, object> funcDistinct)
        {
            this._funcDistinct = funcDistinct;
        }

        public bool Equals(Product x, Product y)
        {
            return _funcDistinct(x).Equals(_funcDistinct(y));
        }

        public int GetHashCode(Product obj)
        {
            return this._funcDistinct(obj).GetHashCode();
        }
    }

var list2 = products.Distinct(new ProductComparare( a => a.Code ));

Upvotes: 1

Related Questions