2009-08-01 15 views
14

Me sale "El objeto no se puede eliminar porque no se encontró en ObjectStateManager". mientras elimina el objeto.Entity Framework Delete Object Problema

aquí están los códigos;

//first i am filling listview control. 
private void Form1_Load(object sender, EventArgs e) 
    { 
     FirebirdEntity asa = new FirebirdEntity(); 

     ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE; 

     foreach (var item in sorgu) 
     { 
      ListViewItem list = new ListViewItem(); 
      list.Text = item.AD; 
      list.SubItems.Add(item.SOYAD); 
      list.Tag = item; 
      listView1.Items.Add(list); 

     } 
//than getting New_table entity from listview's tag property. 
private void button3_Click(object sender, EventArgs e) 
    { 

      using (FirebirdEntity arama = new FirebirdEntity()) 
      { 

       NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag; 
       arama.DeleteObject(del); 
       arama.SaveChanges(); 


      }} 

Respuesta

28

Necesitas attach el objeto a la ObjectContext. Pruebe:

NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag; 
arama.Attach(del); 
arama.DeleteObject(del); 
arama.SaveChanges(); 

Los objetos adjuntos son rastreados por ObjectContext. Esto es necesario para realizar borrados y actualizaciones. Puede leer más sobre attaching objects en MSDN.

Editar para aclarar acopla/desacopla:

private void Form1_Load(object sender, EventArgs e) { 
    FirebirdEntity asa = new FirebirdEntity(); 

    ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE; 
    foreach (var item in sorgu) { 
     asa.Detach(item); 
     // add to listView1 
    } 
} 

Además, debe envolver el uso de ObjectContext s en using bloques.

+0

Estoy obteniendo este error ahora; Un objeto de entidad no puede ser referenciado por varias instancias de IEntityChangeTracker. –

+0

Debe separarlo del ObjectContext que le proporcionó la entidad. Llame a ObjectContext.Detach con el objeto como parámetro. – jason

+0

ahora estoy obteniendo un error como "el objeto no se puede separar porque no está conectado". :( –

5

En el método de "Form1_Load" se crea una primera instancia de su contexto "FirebirdEntity" un relleno ListViewItem con las entidades seleccionadas de este contexto

En el método de "Button3_Click" se crea una nueva, segunda instancia de su Contexto "FirebirdEntity". Luego intenta eliminar una entidad en este SEGUNDO contexto, que fue seleccionado en el PRIMER contexto.

Utilice la misma instancia de su contexto en sus dos métodos y todo funcionará bien.

(Alternativamente puede seleccionar la entidad que desea eliminar una de su segundo contexto y elimine esta entidad en lugar del origen uno)

2

lo general por un eliminar la base de datos que utilizo este tipo de consulta LINQ, siempre funciona a menos que tenga una restricción de clave externa:

int id = convert.toint32(some text field from the page); 
entity data = new entity(); 
var del = (from record in data.records 
      where record.id == id 
      select record).FirstOrDefault(); 
data.deleteObject(del); 
data.saveChanges(); 

Espero que esto ayude.

3

Ejecuté una consulta linq dentro de mis métodos de DomainService y luego eliminé el resultado, por lo que mientras el primer fragmento fallaba con el error "El objeto no se puede eliminar porque no se encontró en ObjectStateManager", el segundo fragmento funcionó.

public void DeleteSharedDoc(SharedDocs shareddoc) 
{ 
     this.ObjectContext.SharedDocs.DeleteObject(shareddoc); 
} 

Esto funcionó:

public void DeleteSharedDoc(SharedDocs shareddoc) 
{ 
var query = (from w in this.ObjectContext.SharedDocs 
      where w.UserShareName == shareddoc.UserShareName 
      && w.UserShareUsersEmail == shareddoc.UserShareUsersEmail 
      && w.DocumentId == shareddoc.DocumentId 
      select w).First(); 
this.ObjectContext.SharedDocs.DeleteObject(query); 
} 
2

Supongamos que tengo un objeto llamado Departamento, con una clave sustituta DepartmentUUID

DDL se ve así:

CREATE TABLE [dbo].[Department] 
    ( 
      DepartmentUUID [UNIQUEIDENTIFIER] NOT NULL 
     , DepartmentName varchar(24) not null 
     , CreateDate smalldatetime not null 
    ) 
GO 


ALTER TABLE [dbo].[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED (DepartmentUUID) 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE (DepartmentName) 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_DepartmentUUID] DEFAULT (NEWSEQUENTIALID()) FOR DepartmentUUID 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_CreateDate] DEFAULT (CURRENT_TIMESTAMP) FOR CreateDate 
GO 

Ahora para el marco de la entidad código. Las partes importantes son: 1. Usando el método AttachTo. 2. Creando un objeto temporal y estableciendo el valor de la clave primaria del mismo. (clave sustituta).

public int DeleteDepartment(Guid departmentUUID) 
{ 

    int returnValue = 0; 

    Department holder = new Department(); 
    holder.DepartmentUUID = departmentUUID; // DepartmentUUID is the primary key of this object (entity in the db) 

    using (MyContectObject context = new MyContectObject()) 
    { 
     context.AttachTo("Departments", holder); 

     context.DeleteObject(holder); 

     int numOfObjectsAffected = context.SaveChanges(); 
     returnValue = numOfObjectsAffected; 

     context.Dispose(); 
    } 

    return returnValue; 

} 
+2

Las últimas 4 líneas deberían ser solo esto: return context.SaveChanges() ;. También elimine la variable returnValue. ¿Por qué crear tanto ruido inútil en el código? –

+0

Algunos marcos devuelven el objeto que se eliminó. (Http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#remove(int) Algunos frameworks devuelven un bool si el método funcionó. Algunos frameworks devuelven el número de filas afectadas. Algunos frameworks vuelven vacíos. Solo porque no lo hagas, no significa que no hay una necesidad legítima de i. t. Pero sí, mi código podría reducirse usando "returnValue = context.SaveChanges();". (<< Solo para mostrar que no soy inaplicable.) Sí, si lo eliges, puedes eliminar un poco más de código. A veces la legibilidad es preferible a la concisión. – granadaCoder

+0

Sí, lectura. Este código es lo más feo posible. Y no legible A eso me refería. –

1

El asquerosamente horrible truco he utilizado es la siguiente:

var attachedObject = _repository.GetObjectByKey(detachedObject.EntityKey); 

trabaja para una gran cantidad de estos temas. Esperaba encontrar una solución más elegante a este problema al venir aquí. Esto parece hacer el truco.

Cuestiones relacionadas