2014-05-15 11 views
10

sto ottenendo questo errore dopo fare clic su Salva (aggiornamento) la mia forma:Il rapporto non potrebbe essere cambiato perché uno o più delle proprietà chiave esterna è non annullabile in MVC 4

Il rapporto non poteva essere modificato perché una o più proprietà della chiave esterna non sono annullabili. Quando viene apportata una modifica a una relazione, la relativa proprietà della chiave esterna viene impostata su un valore nullo. Se la chiave esterna non supporta valori nulli, deve essere definita una nuova relazione, la proprietà chiave esterna deve essere assegnata a un altro valore non nullo o l'oggetto non correlato deve essere eliminato.

Ecco il mio controller (caso "Salva" nel problema couse swich):

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit(UserModel userModel, string act = null, int idx = 0) 
{ 
    using (var dbContext = new userDbEntities()) 
    { 

     if (userModel.User == null) 
     { 
      userModel.User = new UsersTable(); 
     } 
     var newUser = userModel.User.userID == 0; 
     userModel.CustomTypes = dbContext.CustomTypes.ToList(); 

     switch (act) 
     { 
      case "addcustom": 
       userModel.User.CustomerTables.Add(new CustomerTable 
       { 
        CustomType = new CustomType(), 
        UsersTable = userModel.User 
       }); 
       break; 
      case "deletecustom": 
       userModel.User.CustomerTables.RemoveAt(idx); 
       break; 
      case "save": 
       foreach (var customer in userModel.User.CustomerTables) 
       { 
        customer.CustomType = dbContext.CustomTypes.Find(customer.CustomType.Id_NewCustomerType); 
       } 
       var dbUser = dbContext.UsersTables.Find(userModel.User.userID); 
       dbUser.TimeZoneId = userModel.User.TimeZoneId; 
       foreach (var custom in userModel.User.CustomerTables) 
       { 
         if (custom.CustomerID == 0) 
           dbUser.CustomerTables.Add(custom); 
       } 
       foreach (var custom in dbUser.CustomerTables.ToList()) 
       { 
         var modelCustom = 
           userModel.User.CustomerTables.FirstOrDefault(o => o.CustomerID == custom.CustomerID); 
         if (modelCustom != null) //update it 
         { 
          custom.CustomType = 
            dbContext.CustomTypes.Find(modelCustom.CustomType.Id_NewCustomerType); 
         } 


         if (userModel.User.CustomerTables.All(o => o.CustomerID != custom.CustomerID)) 
           dbUser.CustomerTables.Remove(custom); 
        } 
        dbContext.SaveChanges(); 
        break; 
     } // end switch statements 
     return View("Edit", userModel); 
    } 
} 

Qualsiasi idea di ciò che è sbagliato ...

+0

Ok se cambia dbUser.CustomerTables.Remove (personalizzato); to dbContext.Entry (custom) .State = EntityState.Deleted; correggi il problema, ma poi aggiungi semplice (salva non funziona) –

+0

possibile duplicato di [La relazione non può essere modificata perché una o più proprietà di chiave esterna non sono annullabili] (http://stackoverflow.com/questions/5538974/the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-pro-pro) –

risposta

4

C'è un modo più semplice per risolvere questo problema.
In realtà è perché hai una relazione uno a molti. Quando si desidera eliminare 1 lato, si hanno due scenari; Puoi scegliere la cancellazione a cascata o puoi scegliere nessuna.
Se si seleziona la prima opzione, tutte le entità laterali verranno eliminate quando si elimina il lato 1. È possibile impostare questa opzione nel Diagramma entità. Devi solo selezionare la relazione e impostare la proprietà "End1 OnDelete" su Cascade.

+0

Esiste un comando per contrassegnare l'istruzione delete da eseguire senza cascata da C#/Codice EntityFramework? –

0

Si è verificato questo messaggio, è risultato che stavo contrassegnando l'oggetto come modificato dopo averlo rimosso dalla sua raccolta invece di eliminarlo.

Ad esempio, non si desidera chiamare context.Entry (child) .State = EntityState.Modified;
se in effetti si sta tentando di eliminare il bambino.

invece, così come la rimozione del bambino dalla collezione provare qualcosa di simile context.DeleteObject (bambino)

  • non ho il codice esatto perché la mia esperienza è stata con Devexpress XAF ObjectSpace che può essere eseguire il cast in ObjectContext utilizzando ((EFObjectSpace) objectSpace) .ObjectContext;
0

Ho riscontrato questo problema, è complicato da spiegare (quindi, per favore perdona l'analogia), la buona notizia è che la soluzione è molto semplice.

Suppongo di avere un record con una relazione uno a molti, che ha anche una relazione. (Una "Macchina" ha un numero di "Persone", "Persone" hanno un numero di "Bambini"). L'errore si verifica quando si rimuovono le persone dall'auto. Fare un db.Cars.Remove(person);. Ha causato un errore non correlato. Per risolvere il problema, ho fatto un db.Cars.Persons.RemoveRange(children); < --- Dopo questo ho riscontrato l'errore come indicato in questa domanda. Per risolvere questo problema rimuovere i figli del bambino dal database (non dal "Parent" ma dal database stesso) db.Children.RemoveRange(childrenOfPeople);.

Questa è la soluzione più pulita al problema utilizzando correttamente il framework di entità senza impostare lo stato dei record. Spero che aiuti qualcuno.

Problemi correlati