What would cause the Entity Framework to save an unloaded (but lazy loadable) reference over existing data?

If I understand right you have something like this:

public class Company
{
    public Company()
    {
        MainContact = new Contact();
    }

    public int Id { get; set; }
    public virtual Contact MainContact { get; set; }
}

A simple code like this…

var company = context.Companies.Find(1);
context.SaveChanges();

…will indeed create a new empty contact in the database.

The main conclusion I would draw is: Don’t instantiate reference navigation properties in the constructor! (Instantiating navigation collections is OK, I think, as long as you leave their content empty. Also instantiating properties of complex types in the constructor is fine because they are not other entities.)

If you want to make sure to create a new contact with a new company, perhaps a static factory method in the Company class is the better option:

public static Company CreateNewCompany()
{
    return new Company { MainContact = new Contact() };
}

This would also work:

var company = context.Companies.Find(1);
context.Entry(company.MainContact).State = EntityState.Detached;
context.SaveChanges();

But such a procedure looks really ridiculous.

Edit:

It’s by the way automatic change detection which causes the behaviour. This code…

context.Configuration.AutoDetectChangesEnabled = false;
var company = context.Companies.Find(1);
context.SaveChanges();

…doesn’t create a new contact. It’s the change detection working internally in SaveChanges Find which thinks to identify the MainContact in company as a new entity and puts it into Added state into the context.

Leave a Comment