Sequence contains no matching element

C#LinqException

C# Problem Overview


I have an asp.net application in which I am using linq for data manipulation. While running, I get the exception "Sequence contains no matching element".

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;
        }
    }
}

C# Solutions


Solution 1 - C#

Well, I'd expect it's this line that's throwing the exception:

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

First() will throw an exception if it can't find any matching elements. Given that you're testing for null immediately afterwards, it sounds like you want FirstOrDefault(), which returns the default value for the element type (which is null for reference types) if no matching items are found:

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

Other options to consider in some situations are Single() (when you believe there's exactly one matching element) and SingleOrDefault() (when you believe there's exactly one or zero matching elements). I suspect that FirstOrDefault is the best option in this particular case, but it's worth knowing about the others anyway.

On the other hand, it looks like you might actually be better off with a join here in the first place. If you didn't care that it would do all matches (rather than just the first) you could use:

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
}

That's simpler and more efficient IMO.

Even if you do decide to keep the loop, I have a couple of suggestions:

  • Get rid of the outer if. You don't need it, as if Count is zero the for loop body will never execute

  • Use exclusive upper bounds in for loops - they're more idiomatic in C#:

      for (i = 0; i < _lstAcl.Documents.Count; i++)
    
  • Eliminate common subexpressions:

      var target = _lstAcl.Documents[i];
      // Now use target for the rest of the loop body
    
  • Where possible use foreach instead of for to start with:

      foreach (var target in _lstAcl.Documents)
    

Solution 2 - C#

Use FirstOrDefault. First will never return null - if it can't find a matching element it throws the exception you're seeing.

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

Solution 3 - C#

From the MSDN library:

> The First<TSource>(IEnumerable<TSource>) method throws an exception if source contains no elements. To instead return a default value when the source sequence is empty, use the FirstOrDefault method.

Solution 4 - C#

For those of you who faced this issue while creating a controller through the context menu, reopening Visual Studio as an administrator fixed it.

Solution 5 - C#

Maybe using Where() before First() can help you, as my problem has been solved in this case.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMACView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Jakub KoneckiView Answer on Stackoverflow
Solution 3 - C#KBoekView Answer on Stackoverflow
Solution 4 - C#AshView Answer on Stackoverflow
Solution 5 - C#ElnazView Answer on Stackoverflow