Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF 4.1 SaveChanges not updating navigation or reference properties

I'm using code first and can add records without a problem. The database is created properly and is seeded without any problems. But calling SaveChanges() in my Edit action only updates the entity, not any of the navigation or reference properties.

A simplified version of my model:

public class Contact : IMyBaseObject
{
    public Contact()
    {
       this.Delete = false;
       this.ContactTypes = new HashSet<ContactType>();
    }

    public int Id {get; set;}

    public string Name {get;set;}

    public bool Delete {get;set;}

    public virtual ICollection<ContactType> ContactTypes { get; set; }

    public virtual USState USState { get; set; }

}

public class ContactType : MyBaseObject
{
    public ContactType()
    {
    }

    public int Id {get; set;}

    public string Name {get;set;}

    public virtual ICollection<Contact> Contacts {get;set;}
}

public abstract class Territory : MyBaseObject
{
    public int Id {get; set;}

    public string Name {get;set;}

    public string Code {get;set;}
}

public class USState : Territory
{
    public USState()
    {
    }

    // Navigation properties
    public virtual ICollection<Contact> Contacts { get; set; }
}

I won't include the code, but I do have some custom model binding going on. My Edit action (using MVC 3) was not being populated with the ContactType or USState properties. The binding is properly returning a fully populated Contact object with the correct values from the form.

If I understand EF 4.1 properly, I should only have to do the following to persist changes to the database when saving my Contact object:

if(ModelState.IsValid)
{
    context.Entry(contact).State = EntryState.Modified;
    context.SaveChanges();
}

However, only primitive properties are being updated when I do that. I have left out a few things in the above example: I'm using a transaction, a try catch block, and checking if it's a new record.

I have used SQL Profiler and can confirm that the update queries for the ContactType and Territory tables are not being sent to the database server.

The State properties of my navigation and reference properties are Modified, but I have also tried manually setting that:

    context.Entry(contact).Collections("ContactTypes").EntityEntry.State = EntityState.Modified;
    context.Entry(contact).Reference("USState").EntityEntry.State = EntityState.Modified;

I could be mistaken, but I'm pretty sure my code was working under CTP5.

Any ideas? At this point, I'm not sure how I should approach debugging this.

Thanks, Steve

like image 588
Steve Mallory Avatar asked Apr 01 '11 18:04

Steve Mallory


People also ask

How do I use SaveChanges in Entity Framework?

When SaveChanges() is executed to insert, update or delete on the database then Entity framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes.

Does SaveChanges commit?

In Entity Framework, the SaveChanges() method internally creates a transaction and wraps all INSERT, UPDATE and DELETE operations under it. Multiple SaveChanges() calls, create separate transactions, perform CRUD operations and then commit each transaction. The following example demonstrates this.

How do I update EF?

Learn how an entity framework update records to the database. We can update records either in connected or disconnected scenarios. In the connected Scenario, we open the context, query for the entity, edit it, and call the SaveChanges method.

What is SaveChanges?

SaveChanges()Saves all changes made in this context to the database. This method will automatically call DetectChanges() to discover any changes to entity instances before saving to the underlying database.


1 Answers

Try this:

  context.Entry(contact.USState ).State = EntityState.Modified; //////
like image 92
Carbosound1 Avatar answered Oct 21 '22 17:10

Carbosound1