为什么会出现“Sequence contains no elements”这个错误?

26

我收到了一个无效操作异常,栈追踪信息如下。我认为这是因为db.Responses.Where(y => y.ResponseId.Equals(item.ResponseId)).First();没有返回任何结果。我检查了响应数据和userResponseDetails都有一个ResponseId,我也使用了硬编码的值。 我还知道调用这个函数的语句正在添加这个函数应该调用的Responses行。(大约一个月前这个功能是正常的,我不记得更改会导致它崩溃)

[InvalidOperationException: Sequence contains no elements]
   System.Linq.Enumerable.First(IEnumerable`1 source) +269
   System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__0(IEnumerable`1 sequence) +41
   System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +59
   System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +133
   System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +87
   System.Linq.Queryable.First(IQueryable`1 source) +251
   InSight.Controllers.ForecasterController.userResponseDetails(List`1 userResponseDetails) +1039

这里是有问题的代码。

    [HttpPost]
    public JsonResult userResponseDetails(List<ResponseDetailsPartial> userResponseDetails)
    {

        foreach (ResponseDetailsPartial item in userResponseDetails)
        {
            ResponseDetails temp = new ResponseDetails();
            temp.ResponseId = item.ResponseId;
            temp.ResponseDetailVal = item.ResponseDetailVal;
            temp.QuestioChoicesId = item.QuestioChoicesId;
            temp.Response = db.Responses
                  .Where(y => y.ResponseId.Equals(item.ResponseId)).First();
            temp.QuestionChoice = db.QuestionChoices
                   .Where(x => x.QuestionChoicesId.Equals(item.QuestioChoicesId)).First();
          db.ResponseDetails.Add(temp);
        }
        db.SaveChanges();

        return Json(new { ResponseDetailsId = userResponseDetails }, JsonRequestBehavior.AllowGet);
    }

这是调用特定操作的 AJAX:

$.ajax({
         type: "POST",
         url: '/Forecaster/userResponseDetails/',
         data: JSON.stringify(rdetail),
         dataType: 'json',
         contentType: 'application/json',
     })

这是序列化后的rdetail内容:

[{"ResponseId":118,"ResponseDetailVal":0.36,"QuestioChoicesId":null}] 
3个回答

51

再检查一遍。必要时使用调试器。我的猜测是,在userResponseDetails中的某个项目中,此查询未找到任何元素:

.Where(y => y.ResponseId.Equals(item.ResponseId))

所以你不能打电话

.First()

在此基础上。也许可以尝试

.FirstOrDefault()

如果它解决了问题,请勿返回NULL值!这样你就可以看到并诊断问题所在。正确处理这些情况。


1
这有助于确定真正的问题所在。由于我的模型中存在拼写错误,传递的值没有被正确映射。 - schumacherj
3
“disagree. FirstOrDefault会消除该错误,而不是解决问题。返回null可能不是原帖作者想要的。检查为什么可能出现0条记录并相应地采取行动。” - Gianluca Ghettini
1
@GianlucaGhettini 完全同意。这不是一个适当的解决方案,但“作为测试”旨在帮助识别问题,找到真正的解决方案取决于操作员。 - KadekM
如果您不关心某些内容是否存在,例如解析 XML 文件时并非总是存在某个元素,则此解决方案是正确的。 - user890332

8
如果这是有问题的那行代码:
db.Responses.Where(y => y.ResponseId.Equals(item.ResponseId)).First();

这是因为在Responses中没有一个对象的ResponseId == item.ResponseId,如果没有匹配项,则无法获取First()记录。

请尝试以下方法:

var response
  = db.Responses.Where(y => y.ResponseId.Equals(item.ResponseId)).FirstOrDefault();

if (response != null)
{
    // take some alternative action
}
else
    temp.Response = response;
FirstOrDefault() 扩展方法会在未找到匹配项时返回对象的默认值。对于大多数对象(除原始类型之外),其默认值为 null

0
在下一行中。
temp.Response = db.Responses.Where(y => y.ResponseId.Equals(item.ResponseId)).First();

你正在调用 First,但从 db.Responses.Where 返回的集合为空。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接