Sequence不包含匹配元素

时间:2010-10-22 06:11:27

标签: c# linq exception

我有一个asp.net应用程序,我在其中使用linq进行数据操作。在运行时,我得到异常“序列不包含匹配元素”。

if (_lstAcl.Documents.Count > 0)
{
    for (i = 0; i <= _lstAcl.Documents.Count - 1; i++)
    {
        string id = _lstAcl.Documents[i].ID.ToString();                           
        var documentRow = _dsACL.Documents.First(o => o.ID == id);
        if (documentRow !=null)
        {

            _lstAcl.Documents[i].Read = documentRow.Read;
            _lstAcl.Documents[i].ReadRule = documentRow.ReadRule;

            _lstAcl.Documents[i].Create= documentRow.Create;
            _lstAcl.Documents[i].CreateRule = documentRow.CreateRule;

            _lstAcl.Documents[i].Update = documentRow.Update;
            _lstAcl.Documents[i].UpdateRule = documentRow.UpdateRule;

            _lstAcl.Documents[i].Delete = documentRow.Delete;
            _lstAcl.Documents[i].DeleteRule = documentRow.DeleteRule;
        }
    }
}

5 个答案:

答案 0 :(得分:193)

好吧,我希望这条线就是抛出异常:

var documentRow = _dsACL.Documents.First(o => o.ID == id)
如果找不到任何匹配的元素,

First()将抛出异常。鉴于你之后立即测试了null,听起来你想要FirstOrDefault(),它返回元素类型的默认值(对于引用类型为null),如果没有找到匹配项:

var documentRow = _dsACL.Documents.FirstOrDefault(o => o.ID == id)

在某些情况下要考虑的其他选项是Single()(当您认为只有一个匹配元素时)和SingleOrDefault()(当您认为只有一个或零个匹配元素时)。我怀疑FirstOrDefault是这种特殊情况下的最佳选择,但无论如何都值得了解其他人。

另一方面,看起来你最初可能会更好地加入这里。如果您不关心它会使用所有匹配(而不仅仅是第一个),您可以使用:

var query = from target in _lstAcl.Documents
            join source in _dsAcl.Document
            where source.ID.ToString() equals target.ID
            select new { source, target };
foreach (var pair in query)
{
    target.Read = source.Read;
    target.ReadRule = source.ReadRule;
    // etc
}

这更简单更高效的IMO。

即使你决定保持循环,我也有几点建议:

  • 摆脱外部if。你不需要它,好像Count为零,for循环体永远不会执行
  • 在for循环中使用独占上限 - 它们在C#中更具惯用性:

    for (i = 0; i < _lstAcl.Documents.Count; i++)
    
  • 消除常见的子表达式:

    var target = _lstAcl.Documents[i];
    // Now use target for the rest of the loop body
    
  • 尽可能使用foreach代替for开头:

    foreach (var target in _lstAcl.Documents)
    

答案 1 :(得分:31)

使用 FirstOrDefault 。首先永远不会返回null - 如果它找不到匹配的元素,它会抛出你看到的异常。

_dsACL.Documents.FirstOrDefault(o => o.ID == id);

答案 2 :(得分:10)

来自MSDN库的

如果source不包含任何元素,则First(IEnumerable)方法会抛出异常。要在源序列为空时返回默认值,请使用FirstOrDefault方法

答案 3 :(得分:0)

对于那些在通过上下文菜单创建控制器时遇到此问题的人,请以管理员固定的方式重新打开Visual Studio。

答案 4 :(得分:-3)

也许在First()之前使用Where()可以帮助你,因为在这种情况下我的问题已经解决了。

form.jsx