0

I have a list that contains details of Employees(their name, email) and email of the managers they are reporting to. Eg. List<> EmpD

  1. abcd | abcd@gmail.com | abcdmgr@gmail.com
  2. pqr | pqr@gmail.com | pqrmgr@gmail.com
  3. pqrs | pqrs@gmail.com | pqrmgr@gmail.com

Now, i need to send mail to each employees and also to managers with mail body containing names of all the employees under him.

For this, i have used two loops. One to get the manager email and other to check if manager email matches with the one we obtained from first loop. If yes, i send mail to those employees and add them to another new list of employees. After second loop is completed, i have list of all employees under that manager. So now i send him mail, with this new list. Now first loop goes into second iteration and repeats.

The above way is working fine, but i want to optimise it. Currently, the same loop is being traversed twice and despite that i have to create another new list to store similar type of data. Is there a way to group all the employees under same manager, maybe through Linq (i am new to it)?

My Code:

 int countemp = 0;
 while (countemp < listemp.Count())
 {
        var l = listemp[countemp];
        List<EmpRecord> empR = new List<EmpRecord>();

        foreach (var e in listemp)
        {
            if (l.Emp_reportingTo == e.Emp_reportingTo)
            {
                            empR.Add(new EmpRecord() { Emp_Name = e.Emp_Name, EmpIn_Time = e.EmpIn_Time });
                            SendMailEmp(e.Emp_Name,e.Emp_MailID);                      //Send mail to Employee
                            countemp++;
             }
        }
        SendMailMngr(l.Emp_reportingTo, empR);                    //Send mail to Manager
}

EDIT: With the help of suggestions provided , I have tried another code :

var results = from p  in listemp
        group p.Emp_Name by p.Emp_reportingTo into g
        select new { Emp_reportingTo = g.Key, empR = g.ToList() }; 

It works fine. However, i can only fetch one column(Emp_Name) in this. How do i get another column, say Emp_InTime too ?

Ashish Sah
  • 31
  • 2
  • 12
  • 2
    Possible duplicate of [Group by in LINQ](http://stackoverflow.com/questions/7325278/group-by-in-linq) – Raymond Chen Apr 29 '16 at 03:46
  • in C++ `std::map>` where first `string` is manager name and `vector` is his employees. Equivalent to c++ `std::map` in c# is here http://stackoverflow.com/questions/21183414/what-is-c-sharp-equivalent-of-map-in-c – Khalil Khalaf Apr 29 '16 at 04:00

1 Answers1

0

You can do GroupBy on List<Employee> by Emp_reportingTo and then loop the grouped results like this.

var listemp = new List<Employee>();
var groupedEmpByMgr = listemp.GroupBy(x => x.Emp_reportingTo);

foreach (var empsByMgr in groupedEmpByMgr)
{
    var empR = new List<EmpRecord>();

    foreach (var emp in empsByMgr)
    {
        empR.Add(new EmpRecord() { Emp_Name = emp.Emp_Name, EmpIn_Time = emp.EmpIn_Time });
        SendMailEmp(emp.Emp_Name, emp.Emp_MailID);
    }

    SendMailMngr(empsByMgr.Key, empR);
}
hendryanw
  • 1,819
  • 5
  • 24
  • 39
  • It still requires creation of new list. I tried something : "var results = from p in listemp group p.Emp_Name by p.Emp_reportingTo into g select new { Emp_reportingTo = g.Key, empR = g.ToList() }; " But i cant fetch more than one column(Emp_Name) using this. I also want Emp_MailId. Can you help me do that? – Ashish Sah May 02 '16 at 12:15