假"序列不包含任何元素"使用Single()时的异常

时间:2014-06-24 17:09:16

标签: c# linq asp.net-mvc-4

在Linq语句中使用.Single()时,我似乎遇到了抛出错误异常的问题。检查调试器我发现我的列表确实包含我要查找的元素,并且id字段匹配。抛出异常的代码是

public ActionResult Details(int id = 0)
{
    FilterQueue filterqueue = db.FilterQueues.Single(f => f.FilterQueueId == id);

    if (filterqueue == null)
    {
        return HttpNotFound();
    }
    return View(filterqueue);
}

然而,切换到更详细的编码风格是有效的。像这样:

public ActionResult Details(int id = 0)
{
    FilterQueue filterqueue = null;
    foreach (var f in db.FilterQueues)
    {
        if (f.FilterQueueId == id) filterqueue = f;
    }
    if (filterqueue == null)
    {
        return HttpNotFound();
    }
    return View(filterqueue);
}

有趣的是,如果我让代码只是运行异常,它会抓取正确的项目来显示详细信息。

现在,当然,我可以将Single切换到SingleOrDefault,并且工作正常;但是,由于第一个代码块是框架自动编写的,我想了解我做错了什么。如果我犯了一个系统错误,我想以正确的方式纠正它。

2 个答案:

答案 0 :(得分:2)

我认为您正在寻找SingleOrDefault()

在您的代码中,当null永远不会是Single()的结果时,您正在检查null;

这是你想要的:

public ActionResult Details(int id = 0)
{
    FilterQueue filterqueue = db.FilterQueues.SingleOrDefault(f => f.FilterQueueId == id);

    if (filterqueue == null)
    {
        return HttpNotFound();
    }

    return View(filterqueue);
}

答案 1 :(得分:1)

在您的第一个代码中,Single永远不会返回null,如果找不到匹配的元素,则会抛出异常。

  

“序列不包含元素”

如果找不到任何元素,您需要SingleOrDefault才会返回null

使用循环的第二个代码块不是Single的等效表示形式。如果返回的匹配条件多于一个,则Enumerable.Single将抛出异常。然而,你的循环正在返回最后一个匹配的项目。列表中可能有多个项目,但您永远不会知道它。您的循环更类似于LastOrDefault

foreach (var f in db.FilterQueues)
{
    if (f.FilterQueueId == id) filterqueue = f;
}