asp.net-mvc - DbContext 错误?检索新保存的记录后导航属性为空

标签 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 项目引用。

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

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

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

我的 Controller 的 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; }
}

最佳答案

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

在包含中添加了贸易类型

关于asp.net-mvc - DbContext 错误?检索新保存的记录后导航属性为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13655445/

相关文章:

c# - ItextSharp 在尝试打印时需要一个 Dict 对象

jquery - 如何使用苹果浏览器在 Web Asp.net MVC 应用程序中打开文件对话框库?

jquery - StrengthJS 密码强度在一个函数中有效,但在多个函数中不起作用

c# - Entity Framework 与额外字段的多对多关系(数据库优先)

c# - InRequestScope 无法在 ExceptionLogger 上下文中工作

c# - ASP.NET MVC 和 Ninject 2.0 绑定(bind)问题

asp.net-mvc - ASP.NET MVC 复选框组

c# - 如何更改 Entity Framework 为 Datetime 生成 SQL 精度的方式

c# - 组合表达式<Func<T, bool>> 谓词

asp.net-mvc - Controller 构造函数中的 Ninject Mvc 异常处理