实体框架DbSet.Find抛出异常

时间:2012-10-30 22:06:56

标签: asp.net-mvc entity-framework ef-code-first

我正在遵循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属性具有'扩展结果视图将枚举IEnumerable',如果单击它,它会显示我刚从数据库中检索到的预期的两个实体。然而,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位于不同的命名空间或程序集中。 有谁知道为什么创建代码有效而查找没有?

编辑:堆栈跟踪是:

  

System.ArgumentNullException未被用户代码
处理   Message = Value不能为null。参数名称:key Source = mscorlib
  ParamName = key StackTrace:          at System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary 2.ContainsKey(TKey key)          at System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(Type   的EntityType)          在System.Data.Entity.Internal.InternalContext.IsEntityTypeMapped(Type   的EntityType)          在System.Data.Entity.Internal.Linq.InternalSet 1.Find(Object[] keyValues) at System.Data.Entity.DbSet 1.Find(Object [] keyValues)          在C:\ Users \ John \ Documents \ Visual Studio中的Ebuy.Website.Controllers.AuctionsController.Details(Int64 id)   2010 \项目\ Ebuy.Website \ Ebuy.Website \ \控制器AuctionsController.cs:行   26          在lambda_method(Closure,ControllerBase,Object [])          在System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase控制器,Object []参数)          在System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext   controllerContext,IDictionary 2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2   参数)          在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c_ DisplayClass42.b _41()          在System.Web.Mvc.Async.AsyncResultWrapper。&lt;&gt; 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。&lt;&gt; c _DisplayClass37。&lt;&gt; c_ DisplayClass39.b _33()          在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; 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设置的内容,以及访问实体属性时如何进行加载。在我尝试找到一个并且认为可能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参数运行它时,还有其他什么改变了吗?

1 个答案:

答案 0 :(得分: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; }
}