0

When my code reaches CampaignRepository.saveChanges() it gives and error that the relation can not be modified, key properties can not be null. But if I debug it and look into the contents of the current object all primary keys and foreign keys are set. I have no clue why it's going wrong...

public ActionResult Update(LandingPage update)
    {
        Campaign curr = CampaignRepository.FindById(update.CampaignId);
        curr.UpdatePage(update);
        CampaignRepository.SaveChanges();
        return View("Edit", curr);
    }

    public void UpdatePage(LandingPage update)
    {
        foreach (Page page in Pages)
        {
            if (page.Id == update.Id)
            {
                Pages.Remove(page);
                break;
            }
        }
        Pages.Add(update);
    }

de relatie kan niet worden gewijzigd, omdat voor een of meer van de referentiële-sleuteleigenschappen geen null-waarde is toegestaan. Wanneer een relatie wordt gewijzigd, wordt de gerelateerde referentiële-sleuteleigenschap ingesteld op een null-waarde. Als de referentiële sleutel null-waarden niet ondersteunt, moet er een nieuwe relatie worden gedefinieerd, moet de referentiële-sleuteleigenschap worden toegewezen aan een andere waarde die niet null is of moeten het niet-gerelateerde object worden verwijderd.


Update

I changed my Update method to:

  public ActionResult Update(LandingPage update)
        {

            Campaign curr = Campaignrepository.FindById(update.CampaignId);
            PageRepository.Remove(update);
            curr.Pages.Remove(update);
            curr.Pages.Add(update);                          
            Campaignrepository.SaveChanges();

            return View("Edit", curr);
        }

But now it says "The Object can not be removed because it's not found in the ObjectManager".


Update 2

Still "The Object can not be removed because it's not found in the ObjectManager".

 //A campaign has Pages property which is a collection of Pages
//This collection contains a two (no more, no less) objects a LandingPage and a RedeemPage
//both LandingPage and RedeemPage have as base Page
//The objective is to replace the old LandingPage with the new version
public ActionResult Update(LandingPage update)
{
    //Get the campaign it's about
    Campaign curr = Campaignrepository.FindById(update.CampaignId);
    //Set the current Page his foreign key values to null
    curr.GetLanding().Campaign = null;
    curr.GetLanding().CampaignId = 0;
    //Remove the (current) page from the repository/context
    PageRepository.Remove(update);
    //Remove the (current) page from the Campaign collection
    curr.Pages.Remove(update);
    //Add the new version of the page
    curr.Pages.Add(update);      
    //Save the chances => ObjectManager error        
    PageRepository.SaveChanges();          
    return View("Edit", curr);
}
tereško
  • 58,060
  • 25
  • 98
  • 150
Reinard
  • 3,624
  • 10
  • 43
  • 61
  • Hope this helps [http://stackoverflow.com/questions/5538974/the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-pro][1] [1]: http://stackoverflow.com/questions/5538974/the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-pro – Sugandika Apr 03 '12 at 09:14
  • @Sugandika I'm now running into "The Object can not be removed because it's not found in the ObjectManager". I only have one context so that doesn't make sense? – Reinard Apr 03 '12 at 09:26
  • @Sugandika Please do not edit a question to add messages to the OP. That is what comments are for. – Andrew Barber Apr 03 '12 at 09:28

2 Answers2

1

The old child items have to be deleted from the Parent class Campaign one by one manually. Entity Framework doesn't do it. You have to decide what you want to do with the old child items - to throw them away or keep them as they are and assign them to other parent entities. You must tell EF your decision. The child entities cannot live alone without a reference to any parent in the database (due to the foreign key constraint).

Regarding the exception, "The Object can not be removed because it's not found in the ObjectManager", to sort it out you have to set the foreign key values of the child objects into 0. Here's an example as follows. (Suppose your parent object is Campaign myCampaign)

myCampaign.ChildCampaign = null;

has to be done. As well as you have to make the FK id 0.

myCampaign.ChildCampaignId = 0;

I had the same issue with my previous project and was able to solve it doing the same this. Hope this helps.

Sugandika
  • 772
  • 5
  • 10
  • Didn't work curr.GetLanding().Campaign = null; PageRepository.Remove(update); curr.Pages.Remove(update); curr.Pages.Add(update); PageRepository.SaveChanges(); – Reinard Apr 03 '12 at 09:42
  • One small clarification, Will you be able to do something like this in your program before removing the 'update' object? curr.GetLanding().Campaign = null; curr.GetLanding().CampaignId = 0; – Sugandika Apr 03 '12 at 09:45
  • I set it to null and then tried removing it from the repository. But when removing it, I still got the ObjectManager error. edited OP. – Reinard Apr 03 '12 at 10:00
1

you can try change UpdatePage method:

public void UpdatePage(LandingPage update)
{
    var pageToUpdate = this.Pages.Where( p => P.Id == update.Id ).SingleOrDefault();

    if( pageToUpdate != null )
    {   
       // update all properties of old page with new values
       pageToUpdate.Title = update.Title; // for any property of Page
    }
}
ADIMO
  • 1,107
  • 12
  • 24