问题
I have posted this question a while ago but got a partial answer to my issue, so I thought I post more explanation hoping to get a more accurate answer. I have 2 classes:
public class Employee
{
public string Name { get; set; }
public List<Cars> Cars { get; set; }
}
public class Car
{
public int CarID { get; set; }
public CarTypes CarType { get; set; }
public enum CarTypes
{
Van,
SmallCar
}
}
I'm trying to get only All employees that have vans allocated to ignoring those with SmallCars using Lambda, I tried this line:
List<Employee> EmployeesWithVans = AllEmployees.Where(emps => emps.Car.Any(cartype => cartype.CarType == Car.CarTypes.Van)).ToList();
But this gets all employees if at least one van is allocated to an Employee (.Any
) if I try (.All
) it will bring back nothing as not all employees has Van.
Any idea if this can be achieved using nested Lambda?
Thanks.
Edit:
Employee Mark = new Employee();
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 12 });
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 13 });
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.SmallCar, CarID = 14 });
Employee Lisa = new Employee();
Lisa.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 15 });
Lisa.Cars.Add(new Car() { CarType = Car.CarTypes.SmallCar, CarID = 16 });
Lisa.Cars.Add(new Car() { CarType = Car.CarTypes.SmallCar, CarID = 17 });
List<Employee> EmployeesWithVans should contain:
Employee FilteredMark contains:
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 12 });
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 13 });
Employee FilteredLisa contains:
Mark.Cars.Add(new Car() { CarType = Car.CarTypes.Van, CarID = 15 });
回答1:
Try this Instead:
List<Employee> Temp = AllEmployees.Where(emps => emps.Cars.Any(cartype => cartype.CarType == Cars.CarTypes.Van)).ToList();
List<Employee> EmployeesWithVans = (from item in Temp
select new Employee{
Name = item.Name,
Cars = (item.Cars.Where( car => car.CarType == Cars.CarTypes.Van)).ToList()
}).ToList();
This is what i tried (In LINQPAD):
void Main()
{
List<Employee> AllEmployees = new List<Employee>();
List<Cars> lcars1 = new List<Cars>();
Cars car1 = new Cars();
car1.CarType = Cars.CarTypes.Van;
lcars1.Add(car1);lcars1.Add(car1);
Cars car2 = new Cars();
car2.CarType = Cars.CarTypes.SmallCar;
lcars1.Add(car2);
List<Cars> lcars2 = new List<Cars>();
lcars2.Add(car1);lcars2.Add(car2);lcars2.Add(car2);
AllEmployees.Add(new Employee(){ Name="emp1", Cars = lcars1});
AllEmployees.Add(new Employee(){ Name="emp2", Cars = lcars2});
AllEmployees.Add(new Employee(){ Name="emp3", Cars = lcars1 });
AllEmployees.Add(new Employee(){ Name="emp4", Cars = lcars2});
List<Employee> Temp = AllEmployees.Where(emps => emps.Cars.Any(cartype => cartype.CarType == Cars.CarTypes.Van)).ToList();
List<Employee> EmployeesWithVans = (from item in Temp
select new Employee{
Name = item.Name,
Cars = (item.Cars.Where( car => car.CarType == Cars.CarTypes.Van)).ToList()
}).ToList();
EmployeesWithVans.Dump();
}
Output:
回答2:
Is this what you want? (all employees with at least one van, but no smallcar)
var EmployeesWithVans = AllEmployees
.Where(emps => emps.Cars.Any(cartype => cartype.CarType == Cars.CarTypes.Van)
&& !emps.Cars.Any(cartype => cartype.CarType == Cars.CarTypes.SmallCar))
.ToList();
回答3:
The query is correct, it adds an Employee
to the return sequence if it is assigned a van. I'm not quite sure where the question lies, do you think your query will return nothing as not all employees have a van? If yes, this would be the implementation of a Where
operator:
foreach(var elem in input)
{
if (predicate(elem))
yield return elem;
}
The predicate will be applied to all elements in your sequence, if the element fulfills it, it will be returned as part of the sequence.
来源:https://stackoverflow.com/questions/5130152/lambda-with-nested-classes