序列不包含任何元素?

时间:2009-08-24 19:19:30

标签: c# linq

我目前在两个地方使用单个查询从数据库中获取一行。

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).Single();

在检索要将数据放入文本框的行时,查询很好,但是当用于检索行以便对其进行编辑并将其重新放入数据库时​​,它会返回错误“Sequence contains no elements” 。我无法理解为什么它可能在一个实例中找到一个合适的行而不是另一个实例。

(使用ASP.NET MVC和LINQ)

8 个答案:

答案 0 :(得分:316)

来自“Fixing LINQ Error: Sequence contains no elements”:

  

当您收到LINQ错误“序列不包含任何元素”时,通常是因为您使用的是First()Single()命令,而不是FirstOrDefault()SingleOrDefault()

这也可能由以下命令引起:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()

答案 1 :(得分:28)

在这两行中放置断点,或在它之前放置一个Debug.Print,并查看ID包含的内容。

答案 2 :(得分:11)

那么ID在这里是什么?特别是,它是一个局部变量吗?存在一些范围/捕获问题,这意味着可能需要使用第二个变量副本,仅用于查询:

var id = ID;
BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == id
                 select p).Single();

也;如果这是LINQ-to-SQL,那么在当前版本中,如果使用表单,则会获得稍微好一点的行为:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);

答案 3 :(得分:8)

这将解决问题,

var blogPosts = (from p in dc.BlogPosts
             where p.BlogPostID == ID
             select p);
if(blogPosts.Any())
{
  var post = post.Single();
}

答案 4 :(得分:8)

请使用

.FirstOrDefault()

因为如果在结果的第一行中没有信息,则该指令转到默认信息。

答案 5 :(得分:3)

除了已说过的所有其他内容外,您可以在致电DefaultIfEmpty()之前先致电Single()。这将确保您的序列包含某些内容,从而避免InvalidOperationException“序列不包含任何元素”。例如:

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).DefaultIfEmpty().Single();

答案 6 :(得分:0)

错误原因:

  1. 查询from p in dc.BlogPosts where p.BlogPostID == ID select p会返回一个序列。

  2. Single()尝试从步骤1中返回的序列中检索元素。

  3. 根据异常 - 步骤1中返回的序列不包含任何元素。

  4. Single()尝试从步骤1中返回的序列中检索不包含任何元素的元素。

  5. 由于Single()无法从步骤1中返回的序列中获取单个元素,因此会引发错误。

  6. <强>修正:

    确保查询(from p in dc.BlogPosts where p.BlogPostID == ID select p)

    返回一个至少包含一个元素的序列。

答案 7 :(得分:0)

我在计算平均值的函数上也遇到类似的情况。

示例:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Average();

解决的问题:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Count == 0 ? 0 : lstMediaValues.Average();