intento ilegal para establecer una relación 'xyz' entre objetos en diferentes contextos
-
20-09-2019 - |
Pregunta
Estoy utilizando la aplicación de ejemplo CoreDataBooks
de Apple como base para la extracción de datos en un contexto de objeto gestionado secundario en el fondo, y luego la fusión de esos datos en el contexto de objeto gestionado primaria.
Los datos estoy tirando en Book
es una entidad con una relación a uno con una entidad Owner
(llamado "propietario"). La entidad Owner
tiene una relación a varios con los Book
(llamados "libros").
Mis datos es un documento XML de la forma:
<Owner>
<Name>alexpreynolds</Name>
<ID>123456</ID>
</Owner>
<Books>
<Book>Book One</Book>
<Book>Book Two</Book>
...
<Book>Book N</Book>
</Books>
Book One
través Book N
están asociados con uno Owner
("alexpreynolds, 123456"
).
Estoy analizar esto en una instancia Owner
y un NSMutableSet
compuestos de casos Book
.
Cuando intento para salvar la primera vez, se ahorra bien y los datos fusionada se muestra en la vista de tabla.
En el segundo rescate, sin embargo, cuando el contenido XML contiene un nuevo libro, que no funciona.
Esto es lo que sucede:
Entonces intento cargar en un documento XML que contiene un nuevo Book
no está ya en el contexto de objeto gestionado primaria. El nuevo Book
está utilizando el mismo Owner
como la que se asocia con los otros Book
s.
Tengo rutinas que captan a cabo este objeto administrado Owner
única (que ya tengo en mi contexto objeto administrado primaria) y la Book
único que es no que se encuentra en el MOC primaria.
A partir de esto, crea un nuevo objeto Book
en el MOC secundaria, y establecer su relación "owner
" para apuntar a la Owner
único que encontré en el MOC primaria.
Cuando guardo, me sale el siguiente error:
*** Terminating app due to uncaught
exception 'NSInvalidArgumentException',
reason: 'Illegal attempt to establish a
relationship 'owner' between objects in
different contexts
(source = <Book: 0x7803590>
(entity: Book; id: 0x7802ae0 <x-coredata:///
Book/t527F06B2-3EB5-47CF-9A29-985B0D3758862>
; data: {
creationDate = 2009-10-12 06:01:53 -0700;
name = nil;
nameInitial = nil;
operations = (
);
owner = nil;
type = 0;
}) ,
destination = <Owner: 0x78020a0> (entity:
Owner; id: 0x3a56f80 <x-coredata://043AF2F0-1AD0-
4078-A5E8-E9D7071D67D1/Owner/p1> ; data: {
books = "<relationship fault: 0x7801bf0 'books'>";
displayName = alexpreynolds;
ownerID = 123456;
}))'
¿Cómo puedo crear una nueva entidad Book
en el MOC secundaria, por lo que todavía puedo asociarlo con un Owner
preexistente en el MOC primaria?
Solución
No se puede tener relaciones entre objetos en diferentes contextos de objetos gestionados. Así que una manera de moverse que es traer el objeto en el contexto de objeto gestionado.
Por ejemplo:
NSManagedObject *book = // get a book in one MOC
NSManagedObject *owner = // get an owner in a different MOC
[[owner mutableSetValueForKey:@"books"] addObject:[owner.managedObjectContext objectWithID:[book objectID]]];
Así que lo que está haciendo en realidad es buscar el Book
en el mismo contexto de objeto gestionado con owner
. Tenga en cuenta, sin embargo, que esto sólo es posible si book
ya se ha guardado. El contexto de objeto gestionado se va a buscar el objeto en el almacén persistente, por lo que hay que salvar en primer lugar.
Otros consejos
Yo tenía el mismo problema y esta frase me ayudó a resolver el error.
No se puede tener relaciones entre objetos de diferentes administrados contextos de objetos. Así que una manera de moverse por la que se va a llevar el objeto en el contexto de objeto gestionado.
Aquí está mi código (que sustituye las variables para hacer que funcione para usted):
// Have the owner object and get the managedObjectContext
Owner *owner = [[DataFunctions alloc] getCurrentOwner];
NSManagedObjectContext *context = [owner managedObjectContext];
// Create a book and use the manageObjectContext of owner
Book *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:context];
[newQuote setValue: "Book Title" forKey:@"title"];
[newQuote setOwner:owner];
Espero que esto ayude:)
A continuación, usted está tratando de establecer una relación entre dos objetos que son descabellada / creados con un contexto diferente. los datos obligatorios que no le permitirá establecer esas relaciones. Para lograr esto, usted debe buscar el segundo objeto (que está tratando de hacer una relación con) con el contexto del primer objeto con IDobjeto. Ahora usted debería ser capaz de establecer una relación entre estos dos objetos. Por ejemplo:
MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in
let user = User.MR_createEntityInContext(localContext)!
.....
.....
}) //here local context stores data on end of block itself
MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in
let address = Address.MR_createEntityInContext(localContext)!
.....
.....
let user = localContext.objectWithID(self.user!.objectID) as! User
user.address = address
})
Espero que esto le ayudará!
Como dice el error, no está permitido tener una relación en una base de datos de objetos cuyo valor es fijado a otro objeto que tuvo lugar en un contexto diferente. Una manera de evitar esto es esperar hasta después de guardar el nuevo objeto y fusionarla de nuevo en el contexto primario, a continuación, establecer la relación owner
según el caso (ya que los dos objetos están ahora en el mismo contexto, no hay problema con eso) .
book *book = [mainContext ........] //Get book from default context
NSManagedObjectID *objectId = [book objectID];
Book *tmpBook = [tmpContext objectWithID:objectId]; //Now book has the legal relationship
versión Swift ...
context.insert(objectFromOtherContext)