2012-07-22 18 views
5

He intentado lo siguiente para desconectar un gráfico de objetos de entidad, y luego adjuntarlo a un nuevo contexto:¿Se puede separar un gráfico de un ObjectContext y volver a adjuntarlo a otro?

// create a context 
var ctx = new TestEntities(); 
var parents = ctx.Parents; 

// populate the graph 
var newParent = new Parent {Nb = 1, Title = "Parent1"}; 
parents.AddObject(newParent); 
newParent.Children.Add(new Child {Nb = 1, Title = "Child1"}); 

// put all entity objects in Unchanged state before detaching 
ctx.SaveChanges(); 

// detach all entity objects 
foreach (var objectStateEntry in ctx.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)) 
    ctx.Detach(objectStateEntry.Entity); 

// create a new context 
ctx = new TestEntities(); 

// attach graphs to new context 
foreach (var p in parents) 
    ctx.Attach(p); 

Tengo dos problemas con este enfoque:

  1. Después de extraer todos los objetos de entidad, newParent.Children queda vacío
  2. Se genera una excepción InvalidOperationException al volver a adjuntar diciendo que "un objeto de entidad no puede ser referenciado por varias instancias de IEntityChangeTracker".

¿Alguien sabe cómo separar correctamente un gráfico de un ObjectContext y volverlo a conectar a otro?

ACTUALIZACIÓN:

buenas noticias bien para mí, me di cuenta de cómo cambiar la conexión de base de datos subyacente dentro de la misma ObjectContext, así que no tienen que separar/unir más. Si alguien está interesado, así es como lo hago (aquí utilizo SQLite y cambiar el archivo de base de datos):

var sc = ((EntityConnection)ctx.Connection).StoreConnection; 
sc.ConnectionString = @"Data Source=" + newFile + ";"; 

Voy a aceptar la respuesta de Ladislav, ya que parece ser correcta y responde a mi pregunta, ya que se le pidió.

Respuesta

3

Debe crear un clon profundo de todo el gráfico y adjuntarlo a otro contexto. El clon profundo se crea a través de la serialización. El enfoque común es usar DataContractSerializer:

var serializer = new DataContractSerializer(typeof(Parent)); 
serializer.WriteObject(stream, attachedEntity); 
stream.Seek(0, SeekOrgin.Begin); 
detachedEntity = (Parent)serializer.ReadObject(stream); 

para hacer este trabajo sus entidades no deben contener referencias circulares (de los padres tiene la propiedad de navegación para infantil y tiene la propiedad de navegación para los padres) o si debe utilizar DataContract(IsReference=true) y DataMember atributos de sus entidades para informar al serializador que debe seguir las referencias para resolver el problema de referencia circular.

+0

No quiero hacer una copia porque tengo una pila de deshacer/rehacer que se refiere a los objetos en el gráfico, y no quiero desechar la pila cuando cambio el ObjectContext. ¿Conoces algún otro enfoque que pueda usar para cambiar el contexto, o solo su objeto de conexión, mientras sigas usando el mismo gráfico? –

+1

En tal caso, debe usar el mismo contexto para ambas operaciones porque actualmente no hay forma de separar la entidad y mantener sus relaciones; es por eso que debe hacer una copia para conservarlas. –

+0

Sí, tenía miedo de eso, pero hey, descubrí que puedo cambiar la cadena de conexión subyacente y, por lo tanto, no necesito desconectarme ni anexarme para empezar. –

Cuestiones relacionadas