我通过将数据源设置为通过执行LINQ查询获得的IQueryable
对象来填充FormView。基本上,它返回在某个“Shift”内持有某个“位置”的员工数量。
int shiftID = 1;
var shiftCount = from x in context.Employees.Take(1)
select new
{
ManagerCount = ((from p in context.Persons
where p.PositionID == 1 && p.ShiftID == shiftID && p.IsEmployee == true
select p.PersonId).Count(),
PartTimeCount = ((from p in context.Persons
where (p.PositionID == 2 || p.PositionID == 3) && p.ShiftID == shiftID && p.IsEmployee == true
select p.PersonId).Count(),
etc, etc...
};
那部分工作正常。但是,当我想获得所有班次的员工人数时,我无法弄清楚如何去做:
//Get all shifts 1, 2, and 3
var shiftCount = from x in context.Employees.Take(1)
select new
{
ManagerCount = ((from p in context.Persons
where p.PositionID == 1 && (p.ShiftID == 1 || p.ShiftID == 2 || p.ShiftID == 3) && p.IsEmployee == true
select p.PersonId).Count()
};
这不起作用,因为它当然会返回3个值并给出Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
错误
所以我需要得到返回的三个值的总和(它不总是三个,它取决于位置)
我已经看过使用Sum和LINQ分组的各种方法,但似乎无法解决这个问题。任何人都可以指出我正确的方向吗?
答案 0 :(得分:0)
我建议查看分组示例here:
答案 1 :(得分:0)
我已经为您找到了一些答案,但首先您的查询的第一部分似乎有问题。您在.Take(1)
上正在执行Employees
,这只会为您提供一个x
值。由于您未在查询的其余部分中使用x
,因此使用Employees
是多余的。
现在,由于您的所有查询非常相似,我试图删除重复。首先要做的是为你要过滤的班次获得一个通用的过滤器。
如果你有一个班次,请使用:
int shiftID = 1;
var shifts = new [] { shiftID, };
如果您有多班次,请使用:
var shifts = new [] { 1, 2, 3, };
无论哪种方式,您最终都会得到一个整数数组,表示您想要过滤的变换。以下所有答案都需要此shifts
数组。
然后为这些班次中的员工定义一个查询,无论现在如何。
var employeesInShifts =
from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
select p;
所以你可以这样得到班次计数:
var shiftCount =
new
{
ManagerCount = employeesInShifts
.Where(p => p.PositionID == 1)
.Count(),
PartTimeCount = employeesInShifts
.Where(p => p.PositionID == 2 || p.PositionID == 3)
.Count(),
// etc
};
或许更适合您的方法是将employeesInShifts
查询转换为字典,然后从字典中提取值。
var employeesInShifts =
(from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
group p by p.PositionID into gps
select new
{
PositionID = gps.Key,
Count = gps.Count(),
})
.ToDictionary(pc => pc.PositionID, pc.Count);
var shiftCount =
new
{
ManagerCount = employeesInShifts[1],
PartTimeCount = employeesInShifts[2] + employeesInShifts[3],
// etc
};
这种方法的缺点是,在获取值之前,您确实应该检查字典是否具有每个PositionID
的值。
可以通过引入您希望字典具有的位置ID数组并在其上加入结果来解决这个问题。
var positionIDs = new [] { 1, 2, 3, };
var employeesInShifts =
(from p in context.Persons
where p.IsEmployee
where shifts.Contains(p.ShiftID)
where positionIDs.Contains(p.PositionID)
select p).ToArray();
var allPositionEmployeesInShifts =
from pid in positionIDs
join p in employeesInShifts on pid equals p.PersonId into gps
select new
{
PositionID = pid,
Count = gps.Count(),
};
var countOfPositionID =
allPositionEmployeesInShifts
.ToDictionary(x => x.PositionID, x => x.Count);
var shiftCount =
new
{
ManagerCount = countOfPositionID[1],
PartTimeCount = countOfPositionID[2] + countOfPositionID[3],
// etc
};
现在可以保证您的最终字典将包含您想要查询的所有位置ID的计数。
请告诉我这是否有效,或者您是否真的需要加入Employees
表等。