【问题标题】:Entity Framework DbSet.Find throws exception实体框架 DbSet.Find 抛出异常
【发布时间】:2012-10-20 08:09:09
【问题描述】:

我正在关注 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
参数名称=键堆栈跟踪: 在 System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.ContainsKey(TKey 键) 在 System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(类型 实体类型) 在 System.Data.Entity.Internal.InternalContext.IsEntityTypeMapped(类型 实体类型) 在 System.Data.Entity.Internal.Linq.InternalSet1.Find(Object[] keyValues) at System.Data.Entity.DbSet1.Find(Object[] keyValues) 在 C:\Users\John\Documents\Visual Studio 中的 Ebuy.Website.Controllers.AuctionsController.Details(Int64 id) 2010\Projects\Ebuy.Website\Ebuy.Website\Controllers\AuctionsController.cs:line 26 在 lambda_method(闭包,ControllerBase,对象 []) 在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器,Object[] 参数) 在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext 控制器上下文,IDictionary2 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 异步结果) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.c_DisplayClass37.c_DisplayClass39.b_33() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.c_DisplayClass4f.b_49() 内部异常:

编辑 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 参数运行它时是否有其他变化?

【问题讨论】:

  • 能否请您也发布堆栈跟踪?
  • 表的Id列是否标记为主键?
  • 您使用的是 4.0 还是 4.5 哪个 .net 版本?引用的EntityFramework.dll 的确切版本号是多少?
  • 你为什么不使用 lambda 来传递条件/谓词? rep.Find(a =&gt; a.Id == id)
  • @Rikkos:DbSet Find(object[] keyvalues) 的签名 (msdn.microsoft.com/en-us/library/…)

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


【解决方案1】:

在 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; }
}

【讨论】:

  • 感谢 Key decorator 的建议。
猜你喜欢
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多