Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不同字段上的多个LINQ聚合函数应用于整个集合_Linq - Fatal编程技术网

不同字段上的多个LINQ聚合函数应用于整个集合

不同字段上的多个LINQ聚合函数应用于整个集合,linq,Linq,有人能给我一些提示吗。基本上,我希望将不同字段上的不同聚合函数(Count、Sum、Min)应用于整个集合(不是真正的groupping),并以匿名类型的字段形式返回结果。 比如: var employees = new[] { new { Name = "John Smith", Gender="M", DateOfHiring=new DateTime(2004, 10, 22), Salary=60000 }, new { Name = "Jane Smith", Gend

有人能给我一些提示吗。基本上,我希望将不同字段上的不同聚合函数(Count、Sum、Min)应用于整个集合(不是真正的groupping),并以匿名类型的字段形式返回结果。 比如:

var employees = new[] {
    new { Name = "John Smith", Gender="M", DateOfHiring=new DateTime(2004, 10, 22), Salary=60000 },
    new { Name = "Jane Smith", Gender="F", DateOfHiring=new DateTime(2008, 5, 22), Salary=55000 },
    new { Name = "Kathleen Smith", Gender="F", DateOfHiring=new DateTime(2006, 10, 22), Salary=75000 },
    new { Name = "David Smith", Gender="M", DateOfHiring=new DateTime(2002, 7, 12), Salary=85000 },
    new { Name = "Mary Smith", Gender="F", DateOfHiring=new DateTime(2009, 6, 15), Salary=55000 }
};

var query = from e in employees
             select new {
                NumberOfMaleEmployees = /* Count Where Gender = 'M' */,
                NumberOfFemaleEmployees = /* Count Where Gender = 'F' */,
                TotalSalaries = /* Sum All */,
                AverageSalary = /* Avg All */,
                LatestEmployee = /* Employee with Min DateOfHiring */
             };
是否可以在一个查询中实现这一点? 提前谢谢
Iulian

从外观上看,您不希望在数组上进行迭代-您只需要:

var query = new {
    NumberOfMaleEmployees = employees.Count(x => x.Gender == "M"),
    NumberOfFemaleEmployees = employees.Count(x => x.Gender == "F"),
    TotalSalaries = employees.Sum(x => x.Salary),
    AverageSalary = employees.Average(x => x.Average),
};
“最新员工”这一点有点棘手——你基本上想要从中获得,这样你就可以写:

LatestEmployee = employees.MaxBy(x => x.DateOfHiring)

(当然,您可以将其包含在上面的查询中)。

您不希望从数组的外观开始迭代它-您只需要:

var query = new {
    NumberOfMaleEmployees = employees.Count(x => x.Gender == "M"),
    NumberOfFemaleEmployees = employees.Count(x => x.Gender == "F"),
    TotalSalaries = employees.Sum(x => x.Salary),
    AverageSalary = employees.Average(x => x.Average),
};
“最新员工”这一点有点棘手——你基本上想要从中获得,这样你就可以写:

LatestEmployee = employees.MaxBy(x => x.DateOfHiring)

(当然,你可以在上面的查询中包括这一点)。

虽然Skeet先生的答案有效,但它确实会导致员工被迭代5次(包括“最新员工”)。你最好直接使用跟踪每个兴趣聚合的
for
循环:

int maleCount = 0;
int femaleCount = 0;
long totalSalary = 0;
double averageSalary = 0.0;
object latestEmployee = null;

for (int i = 0; i < employees.Length; i++)
{
    maleCount += (employees[i].Gender == "M") ? 1 : 0;
    totalSalary += employees[i].Salary;
    if (latestEmployee == null || employees[i].HireDate > latestEmployee.HireDate)
    {
        latestEmployee = employees[i];
    }   
}   

femaleCount = employees.Length - maleCount;
averageSalary = totalSalary / (double)employees.Length;
int malecont=0;
int femalecont=0;
长期工资总额=0;
双倍平均工资=0.0;
对象latestEmployee=null;
for(int i=0;ilatestEmployee.HireDate)
{
latestEmployee=员工[i];
}   
}   
femaleCount=员工。长度-男性计数;
平均工资=总工资/(双倍)员工人数;

我假设员工可以是男性也可以是女性;如果这个假设不成立,你就需要调整你的代码。

虽然Skeet先生的答案有效,但它确实会导致员工被重复5次(包括“最新员工”)。你最好直接使用跟踪每个兴趣聚合的
for
循环:

int maleCount = 0;
int femaleCount = 0;
long totalSalary = 0;
double averageSalary = 0.0;
object latestEmployee = null;

for (int i = 0; i < employees.Length; i++)
{
    maleCount += (employees[i].Gender == "M") ? 1 : 0;
    totalSalary += employees[i].Salary;
    if (latestEmployee == null || employees[i].HireDate > latestEmployee.HireDate)
    {
        latestEmployee = employees[i];
    }   
}   

femaleCount = employees.Length - maleCount;
averageSalary = totalSalary / (double)employees.Length;
int malecont=0;
int femalecont=0;
长期工资总额=0;
双倍平均工资=0.0;
对象latestEmployee=null;
for(int i=0;ilatestEmployee.HireDate)
{
latestEmployee=员工[i];
}   
}   
femaleCount=员工。长度-男性计数;
平均工资=总工资/(双倍)员工人数;

我假设员工可以是男性也可以是女性;如果这个假设不成立,您需要调整代码。

我明白您的观点,但这是否意味着我们应该把LINQ放在一边,只使用直循环?我使用的示例只是为了让我的问题更清楚,在我的实际案例中,我必须从EF实体集合中获取此结果。如果需要使用内存中的数据源进行多个聚合,则需要使用直循环,或者编写自己的扩展方法来隐藏使用直循环的事实。从EF数据源来看,这有点不同,因为EF LINQ提供程序可以生成捕获多个聚合的SQL。在这一点上,数据库可以执行它认为合适的聚合。我确实明白你的观点,但这是否意味着我们应该把LINQ放在一边,只使用直循环?我使用的示例只是为了让我的问题更清楚,在我的实际案例中,我必须从EF实体集合中获取此结果。如果需要使用内存中的数据源进行多个聚合,则需要使用直循环,或者编写自己的扩展方法来隐藏使用直循环的事实。从EF数据源来看,这有点不同,因为EF LINQ提供程序可以生成捕获多个聚合的SQL。在这一点上,数据库可以执行它认为合适的聚合。这是可行的,但我想知道为什么我不应该在数组上迭代,而在这个解决方案中,在我看来,它好像迭代了5次?不管怎样,我把你的答案记下来了。我仍然很好奇我在第一个问题中的表达方式是否可能。@Iulian:是的,这个数组迭代了5次。如果你不想这样做,你将很难在LINQ中优雅地完成它——最好将LINQ放在一边,并在这种情况下使用dlev。反应式扩展在某种程度上是有帮助的,但它也有它自己的诡计。这是可行的,但我想知道为什么我不应该在数组上迭代,而在这个解决方案中,我似乎需要迭代5次?不管怎样,我把你的答案记下来了。我仍然很好奇我在第一个问题中的表达方式是否可能。@Iulian:是的,这个数组迭代了5次。如果你不想这样做,你将很难在LINQ中优雅地完成它——最好将LINQ放在一边,并在这种情况下使用dlev。反应式扩展可以在某种程度上有所帮助,但它有自己的诡计。