Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a new object in LINQ query

Tags:

c#

linq

I have a list of departments. And each department has a list of employees in it. I need to return all employees from this list who were hired after January 15, 2015. But I need to return a list of "Roster" i.e. List<Roster>. I need help with the LINQ query.

Here's my Department class

public class Department
{
   public int DepartmentId { get; set; }
   public string DepartmentName { get; set; }
   public List<Employee> Employees { get; set; } = new List<Employee>();
   public string Location { get; set; }
}

And my employee class looks like this:

public class Employee
{
   public int EmployeeId { get; set; }
   public Guid PersonId { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string Gender { get; set; }
   public DateTime DateOfBirth { get; set; }
   public DateTime HireDate { get; set; }
}

Here's my roster class

public class Roster
{
   public int DepartmentId { get; set; }
   public string DepartmentName { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string Gender { get; set; }
   public DateTime HireDate { get; set; }
}

Here's what my query looks like so far:

var employees = departments.Where(x => x.Employees).Any(o => o.HireDate >= Convert.ToDateTime("1/15/2015")).Select(i => new Roster { ??? }).ToList();

Please keep in mind, I want to return List<Roster> and need to include both department and employee information in the result. I'm not sure how to get some data from Department object and some from Employee to create the Roster class. Thanks.

like image 813
Sam Avatar asked Jan 28 '16 23:01

Sam


2 Answers

var rosters = departments.SelectMany(
    x => x.Employees
      .Where(y => y.HireDate >= Convert.ToDateTime("1/15/2015"))
      .Select(y => new Roster{ DepartmentId = x.DepartmentId, DepartmentName = x.DepartmentName, FirstName = y.FirstName, LastName = y.LastName, Gender = y.Gender, HireDate = y.HireDate})
  ).ToList();

By popular demand – explanation:

departments.SelectMany(x => x.Employees…) – joins employees from all departments in single employee list.

.Where(…) – filters only employees that were hired after specific date

.Select(y => new Roster{…}) – creates Roster object for each selected employee. At this point we have access to both lambda variables (x – represents department, y – employee) and can use them to fill Roster object fields.

Warning: Will give duplicates if employee is assigned to more than one department.

like image 167
M. Buga Avatar answered Oct 09 '22 14:10

M. Buga


general idea like this one, but it should be refactored

        var departments = new List<Department>();
        var employees = new List<Employee>();

        var result = employees
                        .Where(e => e.HireDate >= Convert.ToDateTime("1/15/2015"))
                        .Select(e => new Roster
                        {
                            FirstName = e.FirstName,
                            LastName = e.LastName,
                            Gender = e.Gender,
                            HireDate = e.HireDate,
                            DepartmentId = departments.First(d => d.Employees.Any(ee => e.EmployeeId == e.EmployeeId)).DepartmentId,
                            DepartmentName = departments.First(d => d.Employees.Any(ee => e.EmployeeId == e.EmployeeId)).DepartmentName
                        });
like image 3
Alex S Avatar answered Oct 09 '22 14:10

Alex S