2010-07-06 29 views
25

Estoy usando Entity Framework 4.0 y tengo un problema tonto que no puedo resolver.La propiedad 'Id' es parte de la información clave del objeto y no puede modificarse

Tengo dos tablas:

  1. Contacto: Id (clave primaria), Valor, ContactTypeId (clave externa a ContactType)
  2. ContactType: Id (clave primaria), Tipo (casa, celular, trabajo , etc.)

Entity Framework creado los siguientes dos entidades:

  1. Contacto: id, valor, contactType (NAVIGA ción de la propiedad)
  2. ContactType: Id, Tipo, Contacto (navegación por la propiedad)

estoy usando el siguiente código para conseguir el contacto y actualizar el tipo de contacto de ese contacto en particular:

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

desencadena la siguiente excepción:

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

parece tan simple! ¡No lo entiendo!

+0

duplicado posible de [La propiedad 'text' es parte de la información clave del objeto y no puede ser modificado] (https://stackoverflow.com/questions/4619564/la propiedad text-es-parte-de-la-objetos-Key-información-y-can not-be-modifi) –

Respuesta

11

La entidad que fue creada por el marco no tiene una propiedad contactContactTypeId. Lo eliminó automáticamente y creó la asociación ContactType dentro de la entidad Contact.

La manera de hacerlo funcionar, como sugirió, es crear un objeto ContactType consultando la base de datos y asignándola a contact.ContactType. Por ejemplo:

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

lo sentimos, que estaba haciendo LINQ-SQL no EF. – DaveShaw

5

Trate

contact.ContactType = differentContactType; 

o

contact.ContactTypeId = 3; 

Usted está tratando de ajustar el ID de la ContactType (de contacto) a 3.

1

Existen dos tipos de asociaciones. Asociación independiente donde la clave relacionada solo aparecería como propiedad de navegación. El segundo es la asociación de clave externa donde la clave relacionada se puede cambiar usando clave externa y propiedad de navegación. Entonces puedes hacer lo siguiente.

// opción 1 opción genérica

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

opción 2 opción de clave externa

contact.ContactTypeId = 3; 

// opción genérica trabaja con clave externa y la asociación independiente

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

estoy usando EF 4.0 y WPF y yo tuvimos un problema similar, y .... encontró el problema que resolvió i t (al menos para mí) de una manera muy simple.

Debido a que, como usted, pensé que debe ser simple para actualizar un campo en una tabla (es decir, en su caso: Contacto) que se hace referencia a ForeignKey de otra tabla (es decir, en su caso: ContactType). Sin embargo, el mensaje de error: ".... es parte de la información de la clave del objeto y no se puede modificar." solo aparece cuando intentas actualizar una clave principal (que no era mi intención en absoluto).

tenía un vistazo más de cerca el código XML de mi EntityModel y lo encontraron:

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

Por alguna razón (tal vez hice un poco tonto error dentro de mi base de datos), cuando Visual Studio genera automáticamente para mí la DataModel de mi base de datos, se añadió en esa misma mesa (Contacto), donde quería actualizar el campo (ContactTypeID) una (segunda línea ) segundoPropertyRef.

que acaba de eliminar esa segunda PropertyRef:

<PropertyRef Name="contactTypeID" /> 

tanto, el modelo tienda y el modelo conceptual y .... problema se resolvió :-)

ahí , sigue siendo igual:

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

actualizaciones e inserciones están funcionando sin problemas como un bebé .... :-)

Por lo tanto, una buena idea para comprobar el código XML del modelo de datos para verificar que sólo su PK aparece como PropertyRef. Trabajó para mí ... :-)

21

Este problema se debe a que se hace referencia a un mismo objeto más de una vez. Esto no es una limitación de EF, sino más bien una característica de seguridad para garantizar que no está insertando el mismo objeto con dos ID diferentes. Entonces, para lograr lo que intenta hacer, simplemente cree un nuevo objeto y agregue el objeto recién creado a la base de datos.

** Este problema ocurre con frecuencia dentro de los bucles. Si está utilizando un ciclo while o foreach, asegúrese de tener el nuevo objeto creado DENTRO del cuerpo del bucle.

intente esto:

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

En mi caso, simplemente moviendo el objeto dentro del bucle e incrementando la ID en consecuencia, resolvió el problema. ¡¡¡¡¡Muchas gracias!!!!! –

+3

'new Contact();' es un inicializador redundante! –

3

tuve que esto ocurre cuando estaba editando objetos relacionados a partir de dos contextos distintos al mismo tiempo. Ejemplo:

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(); 

Mi caso era un poco más complicado (ya que esto es obviamente bastante estúpida), pero en esencia, esto estaba causando el error en mi caso.

0

En mi caso, quiero duplicar el objeto, pero cambiar el id, así que usar este trabajo

Common.DataContext.Detach(object); 

como un encanto

0

Otro comportamiento extraño en mi caso tengo una mesa sin cualquier sí key.EF primaria crea clave primaria compuesta utilizando todas las columnas, es decir:

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

Y cada vez que hago cualquier operación de actualización se lanza esta excepción:

La propiedad 'Código' es parte de la información de la clave del objeto y no puede modificarse .

Solución: eliminar la tabla de diagrama de EF e ir a su base de datos agregar la clave principal en la tabla que está creando problemas y volver a agregar la tabla al diagrama del EF está todo ahora que tendrá una sola tecla es decir

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

Sólo la esperanza que esto ayuda a otra persona, después de luchar durante horas con este, porque sabía que yo no era la actualización del PK y definitivamente tenía una PK. Tuve el valor PK enlazado a una barra de menú para mostrar el valor PK actual y esto estaba causando el problema.

0

retire primero siguiente Añadir

de sencilla

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

Odio este enfoque. Pero funciona... – visc

0

en mi caso, me acaba de establecer la clave principal para la tabla que le faltaba, haya terminado la edmx mappind y lo hizo el trabajo cuando tou tener la clave primaria tendría solo que esta

<PropertyRef Name="id" /> 

sin embargo, si la clave principal no está establecido, que tendría

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

nota de que Juergen Fink respuesta es un trabajo alrededor

Cuestiones relacionadas