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 ...