我正在遵循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.Dictionary2.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.InternalSet1.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,IDictionary2 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_ DisplayClass81.<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参数运行它时,还有其他什么改变了吗?
答案 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; }
}