2012-10-30 89 views
4

我在ASP.NET MVC 4中使用代碼優先的實體框架(版本4.1)的一個非常基本的例子(使用O'Reilly編程ASP.NET MVC 4中的EBuy示例) 。我已經找到了解決這個問題的方法,到目前爲止都已經畫成空白。基本的問題是這樣的代碼在我的控制器:實體框架DbSet.Find拋出異常

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

拋出ArgumentNullException值不能爲空。參數名稱:鍵。當它擊中rep.Find(id)調用。有趣的是,當它分解代碼時,db.Auctions屬性具有'擴展結果視圖將枚舉IEnumerable',如果單擊它,它會顯示我剛剛從數據庫中檢索到的兩個預期實體。然而,代表對象在檢查時確實存在「兒童無法評估」。

神似 '創建' 這樣的代碼工作好:

​​

這是我的分貝背景:

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存在於不同的名稱空間或程序集中。 有誰知道爲什麼創建代碼的作品和查找不?

編輯:的堆棧跟蹤是:

System.ArgumentNullException了未處理由用戶代碼
消息=值不能爲空。參數名:鍵源= mscorlib程序
PARAMNAME =鍵堆棧跟蹤: 在System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary 2.ContainsKey(TKEY的鍵) 在System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(類型 的EntityType) System.Data.Entity.Internal.InternalContext.IsEntityTypeMapped(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet 1.Find(Object[] keyValues) at System.Data.Entity.DbSet 1.在Ebuy.Website.Controllers.AuctionsController找到(Object [] keyValues) 。詳細信息(Int64 id)在C:\ Users \ John \ Documents \ Visual Studio中 2010 \ Projects \ Ebuy.Website \ Ebuy.Website \ Controllers \ AuctionsController.cs:行在lambda_method在System.Web.Mvc.ActionMethodDispatcher.Execute在System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary的2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary(封閉,ControllerBase,對象[]) (ControllerBase控制器,對象[]參數) parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker。 <> c_ DisplayClass42.b _41() at System.Web.Mvc.Async.AsyncResultWrapper。 <> C_ DisplayClass8 1.<BeginSynchronous>b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult 1.End() 在System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult的 asyncResult) 在System.Web.Mvc.Async.AsyncControllerActionInvoker。 <> c _DisplayClass37。 <> c_ DisplayClass39。b _33() at 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 runtime 4.0.30319 v4.4.0.0)。我添加了DataAccess項目並給它提供了一個不同的 EF(運行時4.0.30319 v4.1.0.0)。我已經將DataAccess項目的引用更改爲與Web應用程序相同的EF,現在我得到了一個不同的異常:InvalidOperationException模型創建時無法使用上下文。在N層應用程序中使用EF時,這似乎是一個問題,所以我會跟進此線程並報告回來。

修復:我讀了一些關於EF中LazyLoading設置的內容,以及在訪問實體屬性時如何進行加載。因爲我沒有真正訪問一個實體的屬性之前,我試圖找到一個和思考,也許惰性加載在EF 5.0的默認,我添加了一個默認的構造函數我EbuyDataContext類,如下所示:

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

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

我還設置將LazyLoadingEnabled參數設置爲false,然後運行它和Voila!成功! 但是,我想我會仔細檢查這一點,所以我評論了LazyLoadingEnabled參數,做了一個乾淨的重建,它仍然工作。我註釋掉了默認的構造函數,現在它仍然有效 - 當我使用LazyLoadingEnabled參數運行它時,有什麼更改?

+0

你也可以發佈stacktrace嗎? – nemesv

+0

該表是否將Id列標記爲主鍵? –

+0

哪個.net版本使用4.0或4.5?引用的'EntityFramework.dll'的確切版本號是什麼? – nemesv

回答

0

在EF(至少4和5)中,延遲加載是默認配置。此外,請嘗試使用KeyAttribute裝飾將您的ID明確標記爲密鑰。

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; } 
} 
+0

感謝關鍵裝飾者的建議。 –

相關問題