簡體   English   中英

序列不包含匹配元素

[英]Sequence contains no matching element

我有一個 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;
        }
    }
}

好吧,我希望是這一行拋出異常:

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)

使用FirstOrDefault First 永遠不會返回 null - 如果它找不到匹配的元素,它會拋出您看到的異常。

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

從 MSDN 庫:

如果源不包含任何元素,則First<TSource>(IEnumerable<TSource>)方法將引發異常。 要在源序列為空時返回默認值,請使用FirstOrDefault方法。

對於在通過上下文菜單創建控制器時遇到此問題的人,以管理員身份重新打開 Visual Studio 修復了它。

也許在 First() 之前使用 Where() 可以幫助你,因為我的問題在這種情況下已經解決了。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM