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;
}
}
}
Best Answer
Well, I'd expect it's this line that's throwing the exception:
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 wantFirstOrDefault()
, which returns the default value for the element type (which is null for reference types) if no matching items are found:Other options to consider in some situations are
Single()
(when you believe there's exactly one matching element) andSingleOrDefault()
(when you believe there's exactly one or zero matching elements). I suspect thatFirstOrDefault
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:
That's simpler and more efficient IMO.
Even if you do decide to keep the loop, I have a couple of suggestions:
if
. You don't need it, as if Count is zero the for loop body will never executeUse exclusive upper bounds in for loops - they're more idiomatic in C#:
Eliminate common subexpressions:
Where possible use
foreach
instead offor
to start with: