Что ж, я ожидаю, что именно эта строка вызывает исключение:
var documentRow = _dsACL.Documents.First(o => o.ID == id)
First()
сгенерирует исключение, если не найдет подходящих элементов.Учитывая, что вы тестируете на null сразу после этого, звучит так, как будто вы хотите FirstOrDefault()
, который возвращает значение по умолчанию для типа элемента (которое является нулевым для ссылочных типов), если не найдено подходящих элементов:
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 никогда не выполнится Используйте эксклюзивные верхние границы для циклов - они более идиоматичны в 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)