0

We have encountered Entity Framework returning NULL values for non-nullable relationships. We work model first. The problem occurs when an entity's relationship has been changed in a different context(or in our real use case: a different thread).
-If the navigation property has NOT been called yet, it will return null.
-If the navigation property HAS been called before OR has a foreign key property included in the entity, it will return the last known value.

  • Lazy loading is enabled for the model
  • I have tested this for Entity framework 4.0 and 6.0 and they both yield the same result

This is an example model:

enter image description here

This is some example test code that demonstrates the problem.

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
}

This code does not use threads like in our real situation, but it describes the same problem. In the real application there can be a whole different application on a different PC modifying the entity in the database.

The question here is, why does this behavior occur? Is this a bug in entity framework, perhaps?

It is clear to us that entity framework cannot retrieve the relationship that existed when the entity was instantiated because of lazy loading, but why won't it load the changed relationship instead? Non nullable entities suddenly receiving NULL values is unexpected and something we have not considered in our code at all(and why should we in the first place?)

Olaf
  • 879
  • 6
  • 19
  • This occurs because each context mean a different transaction. You should call they nested in a TransactionScope. – Fals Jan 27 '14 at 16:09
  • Fals: Our entites are lazily loaded, which means that the property can be called at any time in the program, far after the entity being retrieved from the database. In the meantime the database value can already have been changed by an other instance of context(like in a thread). – Olaf Jan 27 '14 at 16:11
  • 1
    Lazy load has nothing about your issue. You are calling two different context to update something that was not commited yet. That's the issue. You have to use a TransactionScope like this: http://msdn.microsoft.com/en-us/data/dn456843 – Fals Jan 27 '14 at 16:19
  • Lazy loading has everything to do with this. There is merely one context updating the item. The other context has not loaded said item yet. Lazy loading means that said object can be loaded at any time, while in the meantime it can have been updated outside of its context. This is NOT two contexts updating a single object. – Olaf Jan 27 '14 at 17:19

1 Answers1

0

Replace

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

with

context.DossierSet.Include(x => x.Fase).Single(x => x.Id == ID);
Pedro.The.Kid
  • 1,968
  • 1
  • 14
  • 18
  • 1
    This works for the example, but it means that you'd have to include this code at *every* point you're calling an entity in the application, for *every* relationship it has. It does not solve or provide a different approach for the core of this problem: every non nullable entity being at risk of being null – Olaf Jan 27 '14 at 17:20