2

私は非常に基本的なカテゴリモデルID, RootCategoryID, Nameを持っており、子が多いカテゴリがある場合は削除されないため、これを再帰的に実行する必要がありますが、そうするとエラーが発生します。

接続文字列を追加するMultipleActiveResultSets=trueと回避策があることはわかっていますが、これはコード内から解決できるため、このパラメーターを使用することはお勧めできません。これは本当ですか?

エラー

このコマンドに関連付けられている開いているDataReaderがすでにあり、最初に閉じる必要があります。

コード

public ActionResult Delete(int id)
{
    this.DeleteRecursive(id);
    _db.SaveChanges();
    return RedirectToAction("index", "category");
}

private void DeleteRecursive(int id)
{
    // Selecting current category
    var currentCategory = _db.Categories.Where(x => x.ID == id).Single(); // this line
    var childrenCategories = _db.Categories.Where(x => x.RootCategory.ID == id);

    // Check if category has children
    if (childrenCategories.Count() > 0)
    {
        // Loop through children and apply same function recrusively
        foreach (var c in childrenCategories)
        {
            this.DeleteRecursive(c.ID);
        }
    }

    // Category has no children left, delete it
    _db.Categories.Remove(currentCategory);
}
4

2 に答える 2

2

あなたは声明のDataReaderためにオープンのままにしています。childrenCategories

例外は別として、クエリを2回実行していることを意味します。1回はカウントを取得し、もう1回はデータを取得します。

これで問題が解決するはずです。

var childrenCategories = _db.Categories
  .Where(x => x.RootCategory.ID == id)
  .ToList()
;

これにより、SQLステートメントが実行され、すべてのレコードがに実体化されますList
つまり、データがメモリにあり、これDataReaderで完了です。

于 2013-01-14T20:28:00.173 に答える
1

あなたの問題は、foreachループ中に照合を変更しようとしていることだと思います。これは実行できません。

削除するアイテムのリストを作成してから、1つですべて削除してみてください

_db.Remove(itemsToRemove).

それはあなたのためのトリックをするでしょう。

于 2013-01-14T20:26:58.123 に答える