3

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

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

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

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

我在此页面上发现了类似/相同问题的报告。文章作者表示,“我认为这是 DbContext 中的一个小故障。即,外键导航属性的延迟加载不适用于新添加的项目,但许多端导航属性的延迟加载有效很好,例如 Teacher.Classes。此故障仅发生在新添加的项目上。如果您没有为新添加的项目在上面显式加载 Class.Teacher,则如果它尚未在实体框架中的某处加载,它将为 null . 但是,如果它已经在某个地方加载,那么 C.Teacher 可以由实体框架自动解析。而对于 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; }
}
4

2 回答 2

2

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

在包含中添加了贸易类型

于 2012-12-01T02:33:38.240 回答
0

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

于 2016-12-23T19:47:32.740 回答