views:

316

answers:

0

Hi there, I don’t know I am really stuck with this problem and I can’t able to get the solution.

I have this code to update my contact and contact group.

    var originalContact = GetContact(contactToEdit.Id);

        // Update with new group
        originalContact.groups = GetGroup(groupId);// Exception : A referential integrity constraint violation occurred: A property that is a part of referential integrity constraint cannot be changed when the object has a non-temporary key.

        // Save changes
        _entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit);
        _entities.SaveChanges();
        return contactToEdit;

Whenever I update the contact the normal fields i.e. name, email and contact it works fine... But when I try to update the relations i.e. groups it comes with this exception

Exception: A referential integrity constraint violation occurred: A property that is a part of referential integrity constraint cannot be changed when the object has a non-temporary key.

I have tried many solutions but couldn’t able to work around sometimes it create new entry with updated group...

I am totally lost can somebody please help.

[Update]

Hi Alex, I have a service class name ContactManagerService

public class ContactManagerService : IContactManagerService
    {
        private IValidationDictionary _validationDictionary;
        private IContactManagerRepository _repository;


        public ContactManagerService(IValidationDictionary validationDictionary)
            : this(validationDictionary, new EntityContactManagerRepository())
        { }


        public ContactManagerService(IValidationDictionary validationDictionary, IContactManagerRepository repository)
        {
            _validationDictionary = validationDictionary;
            _repository = repository;
        }


        public bool ValidateContact(Contact contactToValidate)
        {
            if (contactToValidate.FirstName.Trim().Length == 0)
                _validationDictionary.AddError("FirstName", "First name is required.");
            if (contactToValidate.LastName.Trim().Length == 0)
                _validationDictionary.AddError("LastName", "Last name is required.");
            if (contactToValidate.Phone.Length > 0 && !Regex.IsMatch(contactToValidate.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
                _validationDictionary.AddError("Phone", "Invalid phone number.");
            if (contactToValidate.Email.Length > 0 && !Regex.IsMatch(contactToValidate.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
                _validationDictionary.AddError("Email", "Invalid email address.");
            return _validationDictionary.IsValid;
        }




public bool EditContact(int id, Contact contactToEdit)
        {
            // Validation logic
            if (!ValidateContact(contactToEdit))
                return false;

            // Database logic
            try
            {
                _repository.EditContact(id,contactToEdit);
            }
            catch
            {
                return false;
            }
            return true;
        }

}

This is making an EditContact Call to EntityContactRepository class

 public class EntityContactManagerRepository : ContactManager.Models.IContactManagerRepository
    {
        private ContactManagerDBEntities _entities = new ContactManagerDBEntities();

        //public Contact GetContact(int id)
        //{
        //    return (from c in _entities.ContactSet
        //            where c.Id == id
        //            select c).FirstOrDefault();
        //}


        public IEnumerable<Contact> ListContacts()
        {
            return _entities.ContactSet.ToList();
        }


  public Contact GetContact(int id)
        {
            return (from c in _entities.ContactSet.Include("groups")
                    where c.Id == id
                    select c).FirstOrDefault();
        }




 public Group GetGroup(int id)
        {
            try
            {
                return (from g in _entities.GroupSet //.Include("contacts")
                        where g.Id == id
                        select g).FirstOrDefault();
            }
            catch
            {
                return new Group();
            }
        }



public Contact EditContact(int groupId, Contact contactToEdit)
        {

var originalContact = GetContact(contactToEdit.Id);

        // Update with new group
        originalContact.groups = GetGroup(groupId);// Exception : A referential integrity constraint violation occurred: A property that is a   part of referential integrity constraint cannot be changed when the object has a non-temporary key.

        // Save changes
        _entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit);
        _entities.SaveChanges();
        return contactToEdit;


}
}

it’s the tutorial from mvc website ... http://www.asp.net/learn/mvc/tutorial-31-cs.aspx

<[Update 2]>

This is my ContactController Code

public ActionResult Edit(int id)
      {
        //var contactToEdit = (from c in _entities.ContactSet
        //                     where c.Id == id
        //                     select c).FirstOrDefault();

        //return View(_repository.GetContact(id)); //; contactToEdit);

        //return View(_service.GetContact(id));


        var contactToEdit = _service.GetContact(id);
        AddGroupsToViewData((int) (contactToEdit.groups.Id));
        return View("Edit", contactToEdit);


    }

    //
    // POST: /Home/Edit/5

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int groupId, Contact contactToEdit)
    {
        if (_service.EditContact(groupId, contactToEdit))
            return RedirectToAction("Index", new { id = groupId });
        AddGroupsToViewData(groupId);
        return View("Edit");
    }

[SOLUTION]

Hi I have made a stupid mistake with the database structure , initially it was like

DROP TABLE IF EXISTS `contentmanagement`.`groups`;
  CREATE TABLE  `contentmanagement`.`groups` (
`Id` int(11) NOT NULL auto_increment,
`Name` varchar(45) NOT NULL,
PRIMARY KEY  (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `contentmanagement`.`contacts`;
CREATE TABLE  `contentmanagement`.`contacts` (
`Id` int(11) NOT NULL auto_increment,
`FirstName` varchar(50) character set utf8 collate utf8_unicode_ci NOT NULL,
`LastName` varchar(50) character set utf8 collate utf8_unicode_ci NOT NULL,
`Phone` varchar(50) NOT NULL,
`Email` varchar(50) NOT NULL,
`GroupId` int(11) NOT NULL,
PRIMARY KEY  USING BTREE (`Id`,'GroupId'),
KEY `FK_contacts_1` (`GroupId`),
CONSTRAINT `FK_contacts_1` FOREIGN KEY (`GroupId`) REFERENCES `groups` (`Id`) ON DELETE   CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I updated it to

  DROP TABLE IF EXISTS `contentmanagement`.`groups`;
    CREATE TABLE  `contentmanagement`.`groups` (
   `Id` int(11) NOT NULL auto_increment,
  `Name` varchar(45) NOT NULL,
   PRIMARY KEY  (`Id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `contentmanagement`.`contacts`;
CREATE TABLE  `contentmanagement`.`contacts` (
`Id` int(11) NOT NULL auto_increment,
`FirstName` varchar(50) character set utf8 collate utf8_unicode_ci NOT NULL,
`LastName` varchar(50) character set utf8 collate utf8_unicode_ci NOT NULL,
`Phone` varchar(50) NOT NULL,
`Email` varchar(50) NOT NULL,
`GroupId` int(11) NOT NULL,
  <b> PRIMARY KEY  USING BTREE (`Id`),
Index(`GroupId`),</b>
KEY `FK_contacts_1` (`GroupId`),
CONSTRAINT `FK_contacts_1` FOREIGN KEY (`GroupId`) REFERENCES `groups` (`Id`) ON DELETE   CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

and it solves my problem Thanks ...