简体   繁体   中英

Creating a new object in LINQ query

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" ie 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.

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.

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
                        });
var rosters = employees.Where(e => e.HireDate > someDate)
               .Select(s => new Roster {
                     LastName = s.FirstName,
                     Dept = s.Department.DepartmentName

Note - For this to work, You'd need to add department property into the employee object..

Or make a join between employees and depts

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM