1

私のコントローラでは、新しいサブカテゴリ オブジェクトを作成し、次のようにデータベースに保存しています。

    [Authorize(Roles = "administrator")]
    [HttpPost]
    public ActionResult Create(CategoryViewModel viewmodel, HttpPostedFileBase Icon)
    {
        SubCategory subcategory = viewmodel.subcategory;

        subcategory.Category = categorycontroller.getCategoryByName(viewmodel.SelectedValue);

        if (Icon != null && Icon.ContentLength > 0)
        {
            // extract only the filename
            var fileName = Path.GetFileName(Icon.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("../../Content/icons/"), fileName);
            Icon.SaveAs(path);
            subcategory.Icon = fileName;
        }

        if (ModelState.IsValid)
        {
            db.subcategories.Add(subcategory);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(subcategory);
    }

アプリケーションをデバッグした後、コントローラが、新しく作成したサブカテゴリのカテゴリ オブジェクトへの参照を含むすべてのデータを正しく保存していることに気付きました。

しかし、問題は、サブカテゴリで後でデータベースからデータをロードするときに、オブジェクトがカテゴリ オブジェクトへの参照を欠いていることです。

私のビューモデルは次のようになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Web.Mvc;
using SkyLearn.Areas.Categories.Controllers;

namespace SkyLearn.Areas.Categories.Models
{
    public class CategoryViewModel
    {
        public List<SelectListItem> PossibleValues { get; set; }
        public string SelectedValue { get; set; }
        public SubCategory subcategory { get; set; }

        public CategoryController categorycontroller;

        public CategoryViewModel()
        {
            PossibleValues = new List<SelectListItem>();
        }
    }
}

そして、オブジェクトを見つけるカテゴリコントローラーの私のメソッド:

public Category getCategoryByName(string categoryname)
{
    foreach (Category cat in getCategories())
    {
        if (cat.Title == categoryname)
        {
            return cat;
        }
    }
    return null;
}

カテゴリ オブジェクトの参照が消えるのはなぜですか? 私は盲目です。

4

1 に答える 1

1

ここで破棄されるのは、Controller クラスのインスタンス変数である DbContext オブジェクトです。これは、投稿されたコードには表示されません。MVC スキャフォールディング コード ジェネレーターは、(Dispose() メソッドと共に) そこに配置します。仕組みとしては、リクエストが来るとコントローラーが作成され、その中のメソッドが実行され、コントローラーはリクエストの最後に範囲外になります。Dispose() メソッドを削除しても機能します。ただし、IDisposable である DbContext オブジェクトを破棄しているため、そこにあると便利です。データベース接続などのネイティブ リソースを利用するクラスは、IDisposable を実装します。これは、明示的に Dispose() を呼び出す必要があることを意味します。さもないと、データベース接続が開いたままになり、ガベージ コレクタが不確定な時点でオブジェクトをファイナライズするまで、接続プール リークが発生する可能性があります。詳細については、MSDN ドキュメントの IDispose に関するドキュメントを参照してください。

于 2012-04-30T20:44:35.643 に答える