2010-07-06 4 views
25

J'utilise Entity Framework 4.0 et j'ai un problème stupide que je n'arrive pas à comprendre.La propriété 'Id' fait partie des informations clés de l'objet et ne peut pas être modifiée.

J'ai deux tables:

  1. Contact: Id (clé primaire), la valeur, ContactTypeId (clé étrangère à ContactType)
  2. ContactType: Id (clé primaire), type (Home, Cell, travail , etc.)

Entity Framework a créé les deux entités suivantes:

  1. contact: Id, valeur, contactType (Naviga tion de la propriété)
  2. ContactType: Id, Type, Contact (Navigation Propriété)

J'utilise le code suivant pour obtenir le contact et mettre à jour le type de contact pour ce contact particulier:

Contact contact = dbContext.Contacts.Single(c => c.Id == 12345); 
contact.ContactType.Id = 3; 

lève l'exception suivante:

The property 'Id' is part of the object's key information and cannot be modified. 

Il semble si simple! Je ne comprends pas!

+0

double possible de [la propriété « text » fait partie des informations clés de l'objet et ne peut être modifié] (https://stackoverflow.com/questions/4619564/the-property-text-is-part-of-the-objects-key-information-and-can-be-modifi) –

Répondre

11

L'entité qui a été créée par le cadre n'a pas de propriété contact.ContactTypeId. Il l'a automatiquement supprimé et a créé l'association ContactType dans l'entité Contact. Comme vous l'avez suggéré, le moyen de le faire fonctionner est de créer un objet ContactType en interrogeant la base de données et en l'assignant à contact.ContactType. Par exemple:

Contact contact = dbContext.Contacts.Single(c => c.Id == 12345); 
ContactType contactType = dbContext.ContactType.Single(c => c.Id == 3); 
contact.ContactType = contactType; 
+1

Désolé, je fais linq-sql pas EF. – DaveShaw

5

Essayez

contact.ContactType = differentContactType; 

ou

contact.ContactTypeId = 3; 

Vous essayez de définir l'ID du ContactType (du contact) à 3.

1

Il existe deux types d'associations. Association indépendante où la clé associée ne ferait surface que comme propriété de navigation. La seconde est une association de clé étrangère où la clé associée peut être modifiée à l'aide de la clé étrangère et de la propriété de navigation. Donc, vous pouvez faire ce qui suit.

// option 1 option générique

var contacttype = new ContactType{Id = 3}; 
db.ContactTypes.Attach(contacttype); 
customer.ContactType = contacttype; 

Option 2 Option clé étrangère

contact.ContactTypeId = 3; 

// option générique fonctionne avec la clé étrangère et d'association indépendante

contact.ContactReference.EntityKey = new EntityKey("container.contactset","contacttypeid",3); 
2

J'utilise EF 4.0 et WPF et moi avions un problème similaire, et .... a trouvé le problème que j'ai résolu t (au moins pour moi) d'une manière très simple.

Parce que, comme vous, je pensais que ce doit être simple à mettre à jour un champ dans une table (dans votre cas: Contactez-) qui est référencé par un foreignkey d'une autre table (dans votre cas: ContactType).

Cependant, le message d'erreur: ".... fait partie des informations clés de l'objet et ne peut pas être modifié." n'apparaît que lorsque vous essayez de mettre à jour une clé primaire (ce qui n'était pas du tout mon intention).

Had regarder de plus près le code XML de mon EntityModel et ils ont trouvé:

<EntityType Name="Contact"> 
    <Key> 
     <PropertyRef Name="ID" /> 
     <PropertyRef Name="contactTypeID" /> <!-- This second line caused my problem --> 
    </Key> 
    <Property Name="ID" Type="int" Nullable="false" /> 
    ... 
    ... 
</EntityType> 

Pour une raison quelconque (peut-être que je fait une erreur stupide au sein de ma base de données), lorsque Visual Studio autogénéré pour moi la DataModel de ma base de données, at-il ajouté dans ce tableau très (de contact), où je voulais mettre à jour le champ (ContactTypeID) une seconde PropertyRef (deuxième ligne).

Je viens de supprimer cette deuxième PropertyRef:

<PropertyRef Name="contactTypeID" /> 

à la fois, le modèle de magasin et le modèle conceptuel et .... question a été résolue :-)

Par conséquent , reste comme:

<EntityType Name="Contact"> 
    <Key> 
     <PropertyRef Name="ID" /> 
    </Key> 
    <Property Name="ID" Type="int" Nullable="false" /> 
    ... 
    ... 
</EntityType> 

Les mises à jour et les insertions fonctionnent maintenant comme un bébé .... :-)

Par conséquent, bonne idée de vérifier le code XML du modèle de données pour vérifier que seul votre PK est répertorié comme PropertyRef. Travaillé pour moi ... :-)

21

Ce problème se produit parce que vous référencez le même objet plus d'une fois. Ce n'est pas une limitation de EF, mais plutôt une fonction de sécurité pour vous assurer que vous n'insérez pas le même objet avec deux ID différents. Donc, pour réaliser ce que vous essayez de faire, créez simplement un nouvel objet et ajoutez l'objet nouvellement créé à la base de données.

** Ce problème se produit souvent à l'intérieur des boucles. Si vous utilisez une boucle while ou foreach, assurez-vous d'avoir le nouvel objet créé à l'intérieur du corps de la boucle.

essayez ceci:

Contact contact = dbContext.Contacts.Single(c => c.contactTypeId == 1234); 
contact.contactTypeId = 4; 
dbContext.AddObject(contact); 
dbContext.SaveChanges(); 
+2

Dans mon cas, il suffit de déplacer l'objet dans la boucle et d'incrémenter l'ID pour résoudre le problème. Merci beaucoup!!!!! –

+3

'new Contact();' est un initialiseur redondant! –

3

J'ai eu ce qui se passe quand je faisais le montage des objets connexes de deux contextes distincts en même temps. Exemple:

DataContext ctxA = new DataContext(); 
DataContext ctxB = new DataContext(); 

Author orwell = new Author {Name = "George Orwell" }; 
ctxA.Add(orwell); 
ctxB.Add(new Book {Name = "1984", Author = orwell}); 

ctxA.SaveChanges(); 
ctxB.SaveChanges(); 

Mon cas était un peu plus compliqué (comme cela est évidemment tout à fait stupide), mais en substance, cela a été à l'origine de l'erreur dans mon cas.

0

Dans mon cas, je veux dupliquer l'objet, mais changer l'ID, donc dans mon cas, j'utiliser cette

Common.DataContext.Detach(object); 

travail comme un charme

0

Un autre comportement étrange que j'ai une table sans toute key.EF primaire elle-même crée la clé primaire composite en utilisant toutes les colonnes à savoir:

<Key> 
     <PropertyRef Name="ID" /> 
     <PropertyRef Name="No" /> 
     <PropertyRef Name="Code" /> 
    </Key> 

Et chaque fois que je fais une opération de mise à jour, il génère cette exception:

La propriété 'Code' fait partie des informations clés de l'objet et ne peut pas être modifiée.

Solution: supprimer la table de diagramme EF et accédez à votre DB ajouter clé primaire sur la table qui crée problème et une table ajouter à nouveau au schéma EF, il est tout ce qu'il aura maintenant seule touche-à-dire

<Key> 
     <PropertyRef Name="ID" /> 
</Key> 
0

J'espère juste que cela aide quelqu'un d'autre, après avoir lutté pendant des heures avec cela parce que je savais que je ne mettais pas à jour le PK et j'avais définitivement un PK. J'avais la base de données de valeur PK dans une barre de menu pour afficher la valeur PK actuelle et cela était à l'origine du problème.

0

premier Retirez suivant ajouter

pour de simples

public static IEnumerable UserIntakeFoodEdit(FoodIntaked data) 
     { 
      DBContext db = new DBContext(); 
      var q = db.User_Food_UserIntakeFood.AsQueryable(); 
      var item = q.Where(f => f.PersonID == data.PersonID) 
        .Where(f => f.DateOfIntake == data.DateOfIntake) 
        .Where(f => f.MealTimeID == data.MealTimeIDOld) 
        .Where(f => f.NDB_No == data.NDB_No).FirstOrDefault(); 

      item.Amount = (decimal)data.Amount; 
      item.WeightSeq = data.WeightSeq.ToString(); 
      item.TotalAmount = (decimal)data.TotalAmount; 


      db.User_Food_UserIntakeFood.Remove(item); 
      db.SaveChanges(); 

      item.MealTimeID = data.MealTimeID;//is key 

      db.User_Food_UserIntakeFood.Add(item); 
      db.SaveChanges(); 

      return "Edit"; 
     } 
+0

Je déteste cette approche. Mais ça marche ... – visc

0

dans mon cas, je viens de mettre la clé primaire à la table qui était manquante, re fait la mappind edmx et il a fait le travail lorsque vous ont les tOU clé primaire aurait que cette

<PropertyRef Name="id" /> 

si la clé primaire n'est pas définie, vous auriez

<PropertyRef Name="id" /> 
<PropertyRef Name="col1" /> 
<PropertyRef Name="col2" /> 

Notez que Juergen Fink réponse est un travail autour

Questions connexes