延迟加载导航属性

本文关键字:属性 导航 延迟加载 | 更新日期: 2023-09-27 18:30:51

似乎我无法在我的域服务中的包含上放置 where 子句 - 因此我们正在执行一些循环来获取某些查找组所需的数据。

   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,它也将获取所有查找值并将它们放在导航属性中。 我也删除了全部包含在元数据文件中。

澄清一下:我有附加到查找组的查找值。 查找值将分配给机构。 因此,如果我去获取 STATES 查找组的值,我将返回 50 个查找值。 上面的代码。 当我运行此行时_group。InstitutionLookupValues.Add(_value);我的机构查找值 = 100(取所有查找值,而不考虑机构)。但我的计数器显示 50。我在某处获得了所有查找值,但不确定与特定机构相关的查找值。

延迟加载导航属性

我认为这是由于您正在访问修改后的闭包这一事实引起的,即使不是,您也不应该访问。该行

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 关于这个问题的文章:关闭循环变量被认为是有害的。 令人惊讶的是,很少有人意识到这个问题。

此外,折叠查询可能是一个好主意:

var _lookupValues = _institutionLookupValueRepository.All().Where(x => x.InstitutionID == _userProfile.InstitutionID);

通过使用 ToList() 或类似内容。 否则,您将为_lookupGroups中的每个循环重新评估此查询,如果查询是针对数据库的,或者循环很大,这可能会对性能造成严重影响。