2009-03-06 18 views
15

Tengo un modelo en Ado.Net EF. Tengo una relación de uno a muchos y cuando quiero añadir las entidades consigo el errorCómo deshacerse de "Un objeto de entidad no puede ser referenciado por varias instancias de IEntityChangeTracker"?

"Un objeto entidad no puede ser referenceed por varias instancias de IEntityChangeTracker"

Alguna pista?

Algo similar a

Template template = new Template(); 
... 
... 
while (from < to) 
{ 
    Course course = new Course(); 
    ..... 
    template.Course.Add(course); 
    ..... 
} 
courseEntities.AddToTemplate(template); // Problem line 
courseEntities.SaveChanges(); 

Respuesta

17

que estaba recibiendo este mensaje hasta que empecé a almacenar el contexto de datos en el HttpContext.Items propiedad. Esto significa que puede usar el mismo contexto de datos para la solicitud web actual. De esta forma no terminas con 2 contextos de datos que hacen referencia a las mismas entidades.

Aquí es un buen puesto en DataContext Life Management.

Espero que ayude.

de Dave

2

"plantilla", o algo que haga referencia, ya ha sido añadido a courseEntities o otro contexto. No veo nada en el código que muestres que haría eso, pero ciertamente está sucediendo. Tal vez está sucediendo en algunos de los códigos que ha recortado. Mire la propiedad EntityState de "plantilla" en el depurador, y mire también a EntityState de las propiedades de "plantilla". Esto debería ayudarlo a descubrir qué instancia de entidad ya está en un contexto.

+2

* "plantilla, ** o algo que haga referencia **" * - Gracias Craig, que acaba de resolverse * otra * Problema de EF para mí (es decir, ¿con qué 10 problemas de EF me has ayudado ahora?). Este error ocurre no solo si la entidad está unida a otro contexto, sino si el objeto * any * referenciado por esta entidad está adjunto a otro contexto. –

1

Ya me di cuenta del problema. Tengo otra relación y obtengo la otra entidad de otro contexto.

1

Déjame relatar mi experiencia con este error desagradable y señalar el terreno persiguiendo que le llevará más que conduce a una solución tremendamente sencilla.

CompanyGroup es bastante simple. Tiene un nombre y tiene un objeto Company.

empecé con esto:

1  public static void Add(CompanyGroup item) 
2  { 
3   try 
4   { 
5    using (Entities scope = new Entities()) 
6    { 
7    scope.AddToCompanyGroup(item); 
8      scope.SaveChanges(); 
9    } 
10   } 
11   catch (Exception ex) 
12   { 
13    LogException(ex, item); 
14    throw; 
15   }  
16 } 

Y tiene este error:

{"An entity object cannot be referenced by multiple instances of IEntityChangeTracker."}

Por lo tanto, he añadido esto entre las líneas 6 y 7:

 (IEntityWithChangeTracker)item).SetChangeTracker(null); 

Eso me ha premiado con :

{"The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key."}

Así que cambió

scope.AddToCompanyGroup(item); 

a

scope.Attach(item); 

Ahora se quejó:

{"An object with a temporary EntityKey value cannot be attached to an object context."}

(empezando a sonar como una de las chicas con las que salía en mi juventud - nunca contenido, pero estoy divagando)

Hice, pues, la clave de entidad nula (no funcionó) y se utilizó el método de crear nueva (no funcionaba, tampoco)

En el camino, me dio este mensaje, también:

{"The source query for this EntityCollection or EntityReference cannot be returned when the related object is in either an added state or a detached state and was not originally retrieved using the NoTracking merge option."}

La solución?

Reemplazar el núcleo, las líneas 7 y 8, con:

   CompanyGroup newcg = new CompanyGroup(); 
       newcg.GroupName = item.GroupName; 
       newcg.Company = scope.Company.Where(c => c.CompanyID == item.Company.CompanyID).First(); 

     scope.AddToCompanyGroup(newcg); 
       scope.SaveChanges(); 

Esencialmente, me tomaron los datos que se pasan a través de 'tema', y se trasladó a un objeto del mismo tipo que presenta la misma de nueva creación ámbito como el utilizado en el Agregar.

0

Espero que esta sea la solución más simple y correcta. Necesita un contexto de base de datos por httprequest.

Código EF4 primera plantilla Global.asax.cs http://gist.github.com/574505

void MvcApplication_BeginRequest(object sender, EventArgs e) 
{ 
HttpContext.Current.Items[SessionKey] = new Db(); 
} 

void MvcApplication_EndRequest(object sender, EventArgs e) 
{ 
var disposable = HttpContext.Current.Items[SessionKey] as IDisposable; 
if (disposable != null) 
    disposable.Dispose(); 
} 
0

Este problema que fue resuelto por la eliminación del objeto que pongo al día, relaciones adicionales con (virtual) de otras entidades. Solo dejó su ID.

Este es un código incorrecto

dataFileEntity.IterParameterValue = parameterValueEntity.ParameterValue; 
dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id; 
dataFileEntity.ResultParameter = parameterValueEntity.ResultParameter; 
dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id; 
dataFileEntity.RawDataResult = result.Value; 

Esto es correcto

dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id; 
dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id; 
dataFileEntity.RawDataResult = result.Value; 
RequestTestRawDataFileRepository.AddOrUpdate(dataFileEntity); 

Я эту проблему решила, убрав из объекта, который я апдейтила лишние связи с другими сущностями (virtual). Оставила только их id.

+1

Traductor automático me dice que el último párrafo dice 'Tengo este problema resuelto, eliminar del objeto que actualizo es innecesario debido a otras entidades (Virtual). Solo dejando su identificación. – orique

0

Inicialice sus entidades solo una vez.

Al igual que

Si más de una vez inicializar las Entidades.

Usted obtendrá el error:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

ejemplo:

public class Test 

{ 

private Entities db=new Entities(); 

public static void Add(CompanyGroup item) 
    { 
     try 
     { 

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

     } 
     catch (Exception ex) 
     { 
     }  
    } 
} 
Cuestiones relacionadas