【问题标题】:Non nullable navigation property is null in Entity Framework实体框架中不可为空的导航属性为空
【发布时间】:2014-01-27 16:03:24
【问题描述】:

我们遇到了实体框架为不可为空的关系返回 NULL 值。我们先做模特。 当实体的关系在不同的上下文中(或在我们的实际用例中:不同的线程)发生更改时,就会出现问题。
- 如果导航属性还没有被调用,它将返回 null。
- 如果导航属性在或实体中包含外键属性之前已被调用,它将返回最后一个已知值。

  • 为模型启用延迟加载
  • 我已经针对实体框架 4.0 和 6.0 进行了测试,它们都产生了相同的结果

这是一个示例模型:

这是一些演示问题的示例测试代码。

int ID;
using (Model1Container1 context = new Model1Container1())
{
    Dossier d = new Dossier();
    d.Fase = new Fase();
    context.DossierSet.AddObject(d);//generate new object with relationship
    context.SaveChanges();
    ID = d.Id;
}
using (Model1Container1 context = new Model1Container1())
{
    Dossier storedDossier = context.DossierSet.Single(x => x.Id == ID);//retrieve the saved entity
    using (Model1Container1 context2 = new Model1Container1())
    {
        Dossier faseDossier = context2.DossierSet.Single(x => x.Id == ID);//modify the saved entity in a different context
        faseDossier.Fase = new Fase();
        context2.SaveChanges();
    }
    Console.WriteLine(storedDossier.Fase.Id);//attempt to read the changed property. NULL exception here on storedDossier.Fase
}

这段代码不像我们的实际情况那样使用线程,但它描述了同样的问题。在实际应用程序中,可能有一个完全不同的应用程序在不同的 PC 上修改数据库中的实体。

这里的问题是,为什么会出现这种行为?这可能是实体框架中的错误吗?

我们很清楚,实体框架由于延迟加载而无法检索实体实例化时存在的关系,但为什么它不会加载更改的关系呢?不可为空的实体突然接收到NULL 值是出乎意料的,我们在代码中根本没有考虑到这一点(为什么我们首先要考虑?)

【问题讨论】:

  • 发生这种情况是因为每个上下文都意味着不同的事务。您应该将它们称为嵌套在 TransactionScope 中。
  • 错误:我们的实体是延迟加载的,这意味着可以在程序中的任何时间调用该属性,远在从数据库中检索到实体之后。与此同时,数据库值可能已经被其他上下文实例更改(例如在线程中)。
  • 延迟加载与您的问题无关。您正在调用两个不同的上下文来更新尚未提交的内容。这就是问题所在。您必须像这样使用 TransactionScope:msdn.microsoft.com/en-us/data/dn456843
  • 延迟加载与此有关。只有一个上下文更新项目。另一个上下文尚未加载所述项目。延迟加载意味着可以随时加载所述对象,同时它可以在其上下文之外进行更新。这不是更新单个对象的两个上下文。

标签: c# entity-framework c#-4.0 ef-model-first


【解决方案1】:

替换

context.DossierSet.Single(x => x.Id == ID);

context.DossierSet.Include(x => x.Fase).Single(x => x.Id == ID);

【讨论】:

  • 这适用于示例,但这意味着您必须在 每个 点包含此代码,您在应用程序中调用实体,对于 它拥有的每一个关系。它没有解决这个问题的核心,也没有提供一种不同的方法:每个不可为空的实体都有被为空的风险
猜你喜欢
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
相关资源
最近更新 更多