Sequence不包含匹配元素

MAC*_*MAC 102 c# linq exception

我有在我使用的数据操作LINQ的asp.net应用程序.运行时,我得到异常"序列不包含匹配元素".

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 201

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

var documentRow = _dsACL.Documents.First(o => o.ID == id)
Run Code Online (Sandbox Code Playgroud)

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

var documentRow = _dsACL.Documents.FirstOrDefault(o => o.ID == id)
Run Code Online (Sandbox Code Playgroud)

在某些情况下要考虑的其他选项是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
}
Run Code Online (Sandbox Code Playgroud)

这是更简单,更有效的IMO.

即使你决定保持环路,我有几个建议:


Jak*_*cki 33

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

_dsACL.Documents.FirstOrDefault(o => o.ID == id);
Run Code Online (Sandbox Code Playgroud)

  • 只是稍微澄清一下 - 如果您的谓词与空值匹配,则First*可能*通常返回null.它只是不能在这里返回null,因为`o.ID`会在null值上抛出NullReferenceException. (19认同)

KBo*_*oek 10

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