【问题标题】:Linq query throws exception while foreach query works [duplicate]当 foreach 查询有效时,Linq 查询抛出异常 [重复]
【发布时间】:2015-12-15 18:38:03
【问题描述】:

我正在尝试查询一些结果以填充对象列表。当我使用 foreach 执行此操作时,它可以工作,但是当我尝试使用 linq lambda 表达式时,会引发空引用。另外我只不使用 foreach 代码,因为要花很多时间。

有人知道怎么回事吗?

Foreach 代码:

var aux = _myRepository.GetAll();
var processGames = new List<ProcessGamePersonDTO>();

foreach (var item in aux)
{
    var processGame = new ProcessGamePersonDTO
    {
        IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
        IdGame = item.Game.Id,
        GameName = item.Game.Name,
    };

    processGames.Add(processGame);
}

linq lambda 代码:

var aux = _myRepository.GetAll();
var processGames = aux.Select(item => new ProcessGamePersonDTO
{
    IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
    IdGame = item.Game.Id,
    GameName = item.Game.Name,
}).ToList();

此外,如果我将 Item.ProcessPersonList != null &amp;&amp; Item.ProcessPersonList.Any() ? item.ProcessPersonList.Select(x =&gt; x.Process.Id).ToList() : new List&lt;int&gt;(), 替换为一些通用的 int 列表,例如 new List&lt;int&gt;(),它不会引发任何错误。

【问题讨论】:

  • 使用调试器找出什么是空的。
  • 第一个和第二个是相同的,两者都缺少 some 空检查(例如,item.Game)但如果第一个有效,第二个也应该这样做(假设相同输入)
  • 只是好奇。用函数调用替换 ?: 看看会发生什么
  • @DaveZych IDProcessList 中抛出 ArgumentNUllException,并且抛出此错误的参数名称不在此查询使用的任何实体或对象中。
  • 在声明List&lt;...&gt; 时,您将其命名为ProcessGamePersonDTO,之后您在哪里使用processGames?看起来像是语法错误。

标签: c# linq foreach lambda


【解决方案1】:

这相当于你的 foreach,但它可能不会运行得更快:

var aux = _myRepository.GetAll();
var processGames = aux.Select(item => new ProcessGamePersonDTO
{
    IdProcessList = item.ProcessPersonList != null && item.ProcessPersonList.Any()
            ? item.ProcessPersonList.Select(x => x.Process.Id).ToList()
            : new List<int>(),
    IdGame = item.Game.Id,
    GameName = item.Game.Name
}).ToList();

如果这不起作用,那么这是因为评估事物的顺序不同,并且某些事物在执行时会更改源中的值。在评估 ProcessPersonList 或 item.Game 时是否正在进行处理,这可能会更改其中任何一个的值(或 _myRepository.GetAll 返回的值)?

【讨论】:

  • 感谢不加解释的否决票,但上面的代码确实修复了 ProcessGamePersonDTO 的错误使用。
  • 我认为代码中没有任何内容,而此处理可能会改变值。 repository 方法只返回数据库内容,不改变它。
  • ProcessPersonList 是否被延迟加载?如果不是虚函数,那么在foreach中不是一直为null吗?
  • 很高兴您找到了解决方案,但您的解释不太正确。即使使用 IQueryable,该代码在被评估(和填充)之前也不会执行。我猜你也做了其他事情来修复它。喜欢var processGames = aux.Include(x=&gt;x.ProcessPersonList).Include(x=&gt;x.Game).Include(x=&gt;x.ProcessPersonList.Select(y=&gt;y.Process)).Select...
  • 啊,是的,这与.Include(x=&gt;x.ProcessoCandidato) 的作用相同,因为现在您将其包含在 IQueryable 中。您的提供者将知道它需要该信息并急切地加载它而不是懒惰地加载它,我怀疑您的数据类不是设计为这样做的,所以它会将其保留为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-02
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多