Entity Framework inserting new rows instead of updating them

asp.net asp.net-mvc-4 c# entity-framework

Question

When I update data in the database, I run into an issue. Entitiy Framework adds new rows to tables with multiple rows when I update the data (tables that have foreign key).

database design:

Database model

Entity Framework adds a new row by default whenever I update the Phone, Contact, or Tags entity, rather than changing it.

Here is the code I employed:

public string UpdateContact(Contact contact)
{
    if (contact != null)
    {

        int id = Convert.ToInt32(contact.id);
        Contact Updatecontact = db.Contacts.Where(a => a.id == id).FirstOrDefault();
        Updatecontact.firstname = contact.firstname;
        Updatecontact.lastname = contact.lastname;
        Updatecontact.address = contact.address;
        Updatecontact.bookmarked = contact.bookmarked;
        Updatecontact.city = contact.city;
        Updatecontact.notes = contact.notes;
        Updatecontact.Emails1 = contact.Emails1;
        Updatecontact.Phones1 = contact.Phones1;
        Updatecontact.Tags1 = contact.Tags1;
        db.SaveChanges();
        return "Contact Updated";

    }
    else
    {
        return "Invalid Record";
    }
}

EDIT:

This is the EF Model code:

Contact:

public partial class Contact
{
    public Contact()
    {
        this.Emails1 = new HashSet<Email>();
        this.Phones1 = new HashSet<Phone>();
        this.Tags1 = new HashSet<Tag>();
    }

    public int id { get; set; }
    public string firstname { get; set; }
    public string lastname { get; set; }
    public string address { get; set; }
    public string city { get; set; }
    public Nullable<byte> bookmarked { get; set; }
    public string notes { get; set; }

    public virtual ICollection<Email> Emails1 { get; set; }
    public virtual ICollection<Phone> Phones1 { get; set; }
    public virtual ICollection<Tag> Tags1 { get; set; }
}

Similar model phones, emails, and tags (with different name for value)

public partial class Email
{
        public int id { get; set; }
        public int id_contact { get; set; }
        public string email1 { get; set; }

        public virtual Contact Contact1 { get; set; }
}
1
4
8/19/2016 5:52:23 PM

Accepted Answer

Instead of setting new objects, update the properties.

  Updatecontact.Emails1.email1 = contact.Emails1.email1;
  Updatecontact.Phones1.number = contact.Phones1.number;
  Updatecontact.Tags1.tag1 = contact.Tags1.tag1;

Edit: It appears that your contact model has 11-zillion emails, phone numbers, and tags. If so, a straightforward assignment won't function. Instead, you must locate each one when it is sent from the client and update:

 foreach ( var email in contact.Emails1 )
 {
     // first make sure the object is retrieved from the database 
     var updateemail = Updatecontact.Emails1.FirstOrDefault( e => e.id == email.id );
     // then update its properties
     updateemail.email1 = email.email1;
 }

 // do the same for phones and tags
5
12/30/2014 7:47:25 PM

Popular Answer

First off, if you are already receiving the contact by parameter, why do you need to search for it? If so, it produces a new record since you have two separate objects in two different contexts, leading one to believe that you create a new one because you are in a different context.

Try updating with just one object in the same context; EF should automatically identify the object as modified. If not, check to see if your object has EntityState before saving. Modified.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow