4

我正在关注 ASP.NET MVC 4 中代码优先实体框架(4.1 版)的一个非常基本的示例(使用 O'Reilly 的 Programming 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 值不能为空。参数名称: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 位于不同名称空间或程序集中的参考资料。有谁知道为什么 Create 代码有效而 Find 无效?

编辑:堆栈跟踪是:

System.ArgumentNullException 未由用户代码处理
Message=Value 不能为空。参数名称:key Source=mscorlib
ParamName=key StackTrace:位于 System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.ContainsKey(TKey key) at 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.DbSet1.在 C:\Users\John\Documents\Visual Studio 2010\Projects\Ebuy.Website\Ebuy.Website\Controllers\AuctionsController 中的 Ebuy.Website.Controllers.AuctionsController.Details(Int64 id) 中查找(Object[] keyValues) .cs: lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary) 的第 26 行2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 个参数)在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<> c_DisplayClass42.b _41() 在 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 回答