DbContext错误?检索新保存的记录后,导航属性为null

时间:2012-12-01 01:25:53

标签: asp.net-mvc entity-framework ninject lazy-loading repository-pattern

我的ASP.NET MVC 4应用程序使用Entity Framework v5,Ninject和Ninject.MVC3 nuget包,数据存储在SQL Server Express中。使用“EF 5.x DbContext Generator for C#”模板生成模型。 Lazy Loading Enabled在我的edmx中设置为True。

我正在使用存储库模式,我的存储库和上下文存在于ASP.NET MVC 4项目引用的解决方案中的单独项目中。

所以,问题 - 在保存一个视图模型的属性的新对象(“Trade”)之后,我查询该对象的存储库。此时,我希望填充的导航属性为null。请参阅下面的Create()方法中的注释。

如果我从数据库中检索现有的交易(我不仅仅保存了一个),则所有导航属性似乎都已填充。

我在this page找到了类似/相同问题的报告。该文章的作者指出,“我认为这是DbContext中的一个小故障。即,外键导航属性的延迟加载对新添加的项目不起作用,但是许多终端中导航属性的延迟加载很好,例如Teacher.Classes。这个故障只发生在新添加的项目上。如果你没有为新添加的项目明确加载Class.Teacher,如果尚未在Entity Framework中的某处加载它,它将为null但是,如果它已经在某处加载,那么C.Teacher可以由Entity Framework自动解析。而对于ObjectContext,延迟加载适用于所有类型的导航属性。“

我的控制器的Create方法如下所示:

[HttpPost]
public ActionResult Create(TradeViewModel tradeViewModel)
{
    if (ModelState.IsValid)
    {
        _employeesRepository.SaveTrade(tradeViewModel.Trade);
        var trade =
            _employeesRepository.Trades.First(
                x =>
                x.RequesterId == tradeViewModel.Trade.RequesterId &&
                x.RequesterWorkDate == tradeViewModel.Trade.RequesterWorkDate);

        // Null reference encountered below, as trade.TradeType and trade.Employee are both null
        String userMessage = "New " + trade.TradeType.TradeTypeDescription + " requested with '" + ControllerHelpers.GetDisplayName(trade.Employee) + "'";
        TempData["UserMessage"] = userMessage;

        return RedirectToAction("Index");
    }
    return View();
}

员工存储库中的SaveTrade()方法如下所示:

public void SaveTrade(Trade trade)
{
    var data = (from t in _context.Trades
                where t.RequesterId == trade.RequesterId
                      && t.RequesterWorkDate == trade.RequesterWorkDate
                select t);
    if (!data.Any())
    {
        _context.Trades.Add(trade);
    }
    _context.SaveChanges();
}

最后,_employeesRepository中的交易看起来像:

public IQueryable<Trade> Trades
{
    get { return _context.Trades; }
}

2 个答案:

答案 0 :(得分:1)

EF的违约装载可能导致这种情况。尝试像下面那样热切地加载员工

  var trade =
        _employeesRepository.Trades.Include("TradeType").Include("Employee").First(
     x =>
            x.RequesterId == tradeViewModel.Trade.RequesterId &&
            x.RequesterWorkDate == tradeViewModel.Trade.RequesterWorkDate);

如果您尝试查看由EF生成的查询,您可以获得更清晰的图片。我会使用EfProfiler http://www.hibernatingrhinos.com/products/EFProf进行此类分析。您当然可以使用自己喜欢的工具。

希望这会有所帮助。

<强>更新

这里是Julie Lerman的文章链接,可能有助于理解延迟加载概念http://msdn.microsoft.com/en-us/magazine/hh205756.aspx

在include

中添加了tradetype

答案 1 :(得分:0)

您可能正在使用New()创建交易。您应该使用DBContext的Trades.Create()方法。