似乎我无法在我的域服务中的include上放置where子句 - 所以我们正在做一些循环来获取一些lookupGroups所需的数据。
var _lookupGroups = _lookupGroupRepository.All();
var _lookupValues = _institutionLookupValueRepository.All().Where(x => x.InstitutionID == _userProfile.InstitutionID);
int i = 0;
foreach (var _group in _lookupGroups)
{
var _values = _lookupValues.Where(x => x.LookupGroupID == _group.LookupGroupID);
foreach (var _value in _values)
{
_group.InstitutionLookupValues.Add(_value);
i++;
}
Console.WriteLine(_group.GroupName + " " + i.ToString());
}
return _lookupGroups;
我输入的计数器用于对我所看到的内容进行一些验证 - 我们迭代的第一组是状态。我的柜台会说50但我的导航属性会说100,我们每个机构都有一套50(我们有2套)。所以即使我的计数器显示50,它仍然会获取所有查找值并将它们放入导航属性中。我也删除了元数据文件中的所有包含。
澄清:我有附加到lookupGroups的查找值。查找值分配给机构。所以,如果我去获取STATES查找组的值,我将获得50个查找值。上面的代码。当我运行这一行_group.InstitutionLookupValues.Add(_value);我的InstitutionLookupValues = 100(无论机构如何,都取得所有lookupValues)。但我的计数器显示50.在某个地方,我得到的所有查找值都不确定那些与特定机构相关的值。
答案 0 :(得分:3)
我认为这是因为你正在访问一个修改后的闭包,即使它不是,你也不应该这样做。这条线
var _values = _lookupValues.Where(x => x.LookupGroupID == _group.LookupGroupID);
可能没有做你认为它正在做的事情(除非它是C#5)。 lambda是一个委托,闭包将关闭变量,而不是值。这意味着您的代码_group.LookupGroupID
将始终是枚举器最后一次迭代的最后一个值,因此您只能在一个_group.LookupGroupID
上过滤查找值。
尝试将块更改为:
foreach (var _group in _lookupGroups)
{
var currentGroup = _group;
var _values = _lookupValues.Where(x => x.LookupGroupID == currentGroup.LookupGroupID);
foreach (var _value in _values)
{
currentGroup.InstitutionLookupValues.Add(_value);
i++;
}
Console.WriteLine(currentGroup.GroupName + " " + i.ToString());
}
我不确定这是否是问题的原因,但无论如何你都会得到其他奇怪的效果。通过在循环中创建自己的变量,可以避免关闭生成的枚举变量。
看看Eric Lippert的文章:Closing over the loop variable considered harmful。令人惊讶的是,很少有人意识到这个问题。
此外,崩溃查询可能是个好主意:
var _lookupValues = _institutionLookupValueRepository.All().Where(x => x.InstitutionID == _userProfile.InstitutionID);
使用ToList()
或类似内容。否则,您将为_lookupGroups
中的每个循环重新评估此查询,如果查询是数据库,或者循环很大,这可能是一个令人讨厌的性能损失。