4

ASP.NET MVC 4 のコード ファースト エンティティ フレームワーク (バージョン 4.1) の非常に基本的な例に従っています (O'Reilly のプログラミング ASP.NET MVC 4 の EBuy の例を使用)。私はこれに対する解決策を探してきましたが、これまでのところ空白にしています。基本的な問題は、コントローラーの次のコードです。

public ActionResult Details(long id)
    {
        using (var db = new EbuyDataContext())
        {
            var rep = db.Auctions;
            var auction = rep.Find(id);
            return View(auction);
        }
    }

ArgumentNullExceptionをスローします。値を null にすることはできません。パラメータ名: key. rep.Find(id) 呼び出しにヒットしたとき。興味深いことに、コードに割り込むと、db.Auctions プロパティに「Expanding the Results View will enumerate the IEnumerable」があり、クリックすると、データベースから取得されたばかりの 2 つのエンティティが表示されます。ただし、rep オブジェクトを検査すると、「子を評価できませんでした」というメッセージが表示されます。

このような非常によく似た「作成」コードは問題なく動作します。

[HttpPost]
    public ActionResult Create(Auction auction)
    {
        var db = new EbuyDataContext();
        db.Auctions.Add(auction);
        db.SaveChanges();

        return View(auction);
    }

これは私のデータベースコンテキストです:

namespace Ebuy.DataAccess
{
    public class EbuyDataContext : DbContext
    {
        public DbSet<Auction> Auctions { get; set; } 
    }
}

これは私のモデルクラスです:

namespace Ebuy.DomainModel
{
    public class Auction
    {
        public long Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public decimal StartPrice { get; set; }
        public decimal CurrentPrice { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
    }
}

私は、POCO と dbcontext が異なる名前空間またはアセンブリにあることについて話している 1 つの参照を見つけました。Create コードが機能し、Find が機能しない理由を知っている人はいますか?

編集:スタックトレースは次のとおりです。

System.ArgumentNullException はユーザー コードによって処理され
ませんでした Message=Value を null にすることはできません。パラメーター名: キー ソース = mscorlib
ParamName = キー StackTrace: System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.ContainsKey(TKey キー) で System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(Type entityType) で System.Data.Entity. System.Data.Entity.Internal.Linq.InternalSet の Internal.InternalContext.IsEntityTypeMapped(Type entityType)1.Find(Object[] keyValues) at System.Data.Entity.DbSetC:\Users\John\Documents\Visual Studio 2010\Projects\Ebuy.Website\Ebuy.Website\Controllers\AuctionsController の Ebuy.Website.Controllers.AuctionsController.Details(Int64 id) で 1.Find(Object[] keyValues) .cs: System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary) の System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) の lambda_method(Closure , ControllerBase , Object[] ) の 26 行目2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 つのパラメーター) System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_ DisplayClass42.b _41() at System.Web.Mvc.Async.AsyncResultWrapper.<>c_ DisplayClass81.<BeginSynchronous>b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End() で System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) で System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c _DisplayClass37.<>c_ DisplayClass39.b _33() で System.Web .Mvc.Async.AsyncControllerActionInvoker.<>c_ DisplayClass4f.b _49() InnerException:

編集 2:テーブルには主キーとして Id 列があります。 更新: nemesv のコメントに基づいて、バージョンを確認しました。.NET Framework v 4.0 を使用しています。MVC Web アプリは、作成時に Nuget を使用して EF バージョン 5.0 を取得しました (ただし、実際の参照は EF ランタイム 4.0.30319 v4.4.0.0 です)。DataAccess プロジェクトを追加し、別のEF (ランタイム 4.0.30319 v4.1.0.0)への参照を与えました。DataAccess プロジェクトの参照を Web アプリと同じ EF に変更したところ、別の例外が発生しました: InvalidOperationException モデルの作成中はコンテキストを使用できません。これは、N 層アプリケーション全体で EF を使用する場合に問題になるようです。そのため、このスレッドをフォローアップして報告します。

修正: EF の LazyLoading 設定と、エンティティのプロパティにアクセスしたときにどのように読み込みが行われるかについていくつか読みました。エンティティ プロパティを見つけようとする前に実際にエンティティ プロパティにアクセスしていないので、おそらく LazyLoading が EF 5.0 のデフォルトであると考えているため、次のように EbuyDataContext クラスにデフォルト コンストラクタを追加しました。

public class EbuyDataContext : DbContext
{
    public EbuyDataContext()
    {
        //Configuration.LazyLoadingEnabled = false;
    }

    public DbSet<Auction> Auctions { get; set; } 
}

また、LazyLoadingEnabled パラメーターを false に設定して実行すると、出来上がりです。成功!ただし、これを再確認すると思ったので、LazyLoadingEnabled パラメーターをコメントアウトし、クリーンな再構築を行いましたが、それでも機能しました。デフォルトのコンストラクターをコメントアウトしましたが、今でも機能します。LazyLoadingEnabled パラメーターを指定して実行したときに、他に何か変更がありましたか?

4

1 に答える 1

0

EF (少なくとも 4 と 5) では、遅延読み込みがデフォルトの構成です。また、KeyAttribute 装飾を使用して、ID を Key として明示的にマークしてみてください。

public class Auction
{
    [Key]
    public long Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public decimal StartPrice { get; set; }
    public decimal CurrentPrice { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}
于 2012-12-03T18:52:42.600 に答える