データ操作に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;
}
}
}
さて、例外をスローしているのは次の行だと思います:
var documentRow = _dsACL.Documents.First(o => o.ID == id)
First()
は、一致する要素が見つからない場合に例外をスローします。すぐにヌルをテストしていることを考えると、 FirstOrDefault()
のように聞こえます。一致するアイテムが見つからない場合、要素タイプのデフォルト値(参照タイプの場合はヌル)を返します。
var documentRow = _dsACL.Documents.FirstOrDefault(o => o.ID == id)
いくつかの状況で考慮すべきその他のオプションは、 Single()
(一致する要素が1つだけあると思われる場合)および SingleOrDefault()
(一致する要素が1つまたは0あると思われる場合)です。この特定のケースではFirstOrDefault
が最適なオプションであると思われますが、とにかく他のものについて知る価値があります。
一方、実際には、ここで最初に結合を行う方が良いようです。 allマッチ(最初のマッチだけでなく)を行うことを気にしない場合は、以下を使用できます。
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
}
それは、より簡単なandより効率的なIMOです。
あなたがdoループを維持することに決めたとしても、私はいくつかの提案があります:
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を使用します。最初にnullが返されることはありません。一致する要素が見つからない場合は、表示されている例外がスローされます。
_dsACL.Documents.FirstOrDefault(o => o.ID == id);
mSDNライブラリから:ソースに要素が含まれていない場合、First(IEnumerable)メソッドは例外をスローします。ソースシーケンスが空のときにデフォルト値を返すには、FirstOrDefaultメソッドを使用します
コンテキストメニューを使用してコントローラーを作成しているときにこの問題に直面した人のために、管理者としてVisual Studioを再度開いて修正しました。