Linq nested or inner query

c# entity-framework-core linq

Question

Suppose I have a list of employees and each employee has several projects. I can get a given employee using:

var employee = employees.SingleOrDefault(x => x.Id == "id");

But how can I filter also project for the employee?

For example:

var employee = list
  .SingleOrDefault(x => x.Key == employeeKey && 
                        x.Projects.SingleOrDefault(p => p.Key == projectKey));
1
3
11/20/2018 10:09:55 AM

Accepted Answer

If you want to filter down the Projects after getting the Employee you can use a .Select().

var result = employees.Where(e => e.Id == id).Select(e => new Employee
            {
                Id = e.Id,
                Projects = e.Projects.SingleOrDefault(p => p.Key == projectKey)
            }).SingleOrDefault();

So you can get the data you need in one step, but you have to assign the properties by yourself.

Another way is to first get your Employee and then filter down the projects, like BoredomOverload suggested:

var employee = employees.SingleOrDefault(x => x.Id== "id");
employee.Projects = employee.Projects.SingleOrDefault(p => p.Key == projectKey);

Either way you get the employee and the Projects of that Employee filtered.

2
11/20/2018 9:42:20 AM

Popular Answer

SingleOrDefault returns the object if found or null. So, in your case, it returns all employees because you are not testing anything. You just said if the project is there then return it.

Use Any instead which will return a boolean value if exist or not:

var employee = list.SingleOrDefault(x => x.Key == customerKey && x.Projects.Any(p => p.Key == projectKey));

If you need to filter if he has only one project with the specific key:

var employee = list.SingleOrDefault(x => x.Key == customerKey && x.Projects.Count(p => p.Key == projectKey) == 1);

You can also achieve it with SingleOrDefault but test the value with null:

var employee = list.SingleOrDefault(x => x.Key == customerKey && x.Projects.SingleOrDefault(p => p.Key == projectKey) != null);

If you want the return type to be more specific then use the select.

If it didn't work, try to add "include" to the list:

list.Include("Projects").... the rest of the query


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow