Ilegal tentativa de estabelecer uma relação de 'xyz' entre objetos em diferentes contextos
-
20-09-2019 - |
Pergunta
Eu estou usando o da Apple CoreDataBooks
aplicação de exemplo como base para puxar dados para um segundo objeto gerenciado contexto no plano de fundo e, em seguida, mesclar os dados para o principal objeto gerenciado contexto.
Os dados que eu estou puxando em um Book
entidade com um para-um relacionamento com um Owner
entidade (chamada de "proprietário").O Owner
a entidade tem um para-muitos com o relacionamento Book
(chamado de "livros").
Meus dados é um documento XML do formulário:
<Owner>
<Name>alexpreynolds</Name>
<ID>123456</ID>
</Owner>
<Books>
<Book>Book One</Book>
<Book>Book Two</Book>
...
<Book>Book N</Book>
</Books>
Book One
através de Book N
são associados a um Owner
("alexpreynolds, 123456"
).
Eu sou a análise de um Owner
instância e um NSMutableSet
composto de Book
instâncias.
Quando eu tentativa para salvar a primeira vez, ele salva multa e os dados mesclados mostra até no modo de exibição de tabela.
No segundo salvar, no entanto, quando o conteúdo XML contém um novo livro, ele não funciona.
Aqui está o que acontece:
Eu, em seguida, tentar carregar um documento XML que contém um novo Book
já não o principal objeto gerenciado contexto.O novo Book
está a utilizar o mesmo Owner
como o que está associado com o outro Book
s.
Eu tenho rotinas que escolher este exclusivo Owner
objeto gerenciado (que eu já tenho no meu principal objeto gerenciado contexto) e o único Book
que é não encontrado no primário MOC.
A partir deste, criar um novo Book
objeto secundário MOC, e eu definir o seu "owner
"relacionamento para apontar para o único Owner
Eu encontrei a principal MOC.
Quando me salvar, eu recebo o seguinte erro:
*** 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;
}))'
Como faço para criar um novo Book
entidade no secundário MOC, para que eu possa ainda associá-lo com um pré-existentes Owner
no primário MOC?
Solução
Você não pode ter relacionamentos entre objetos em diferentes contextos de objetos gerenciados. Portanto, uma maneira de contornar isso é trazer o objeto para o contexto de objeto gerenciado.
Por exemplo:
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]]];
Então, o que você está fazendo é realmente buscar o Book
no mesmo contexto de objeto gerenciado com owner
. Lembre -se, porém, que isso só é possível se book
já foi salvo. O contexto de objeto gerenciado procurará o objeto na loja persistente, por isso deve ser salvo primeiro.
Outras dicas
Eu tive o mesmo problema e esta frase me ajudou a resolver o erro.
Você não pode ter relações entre objetos em diferentes gerenciado objeto contextos.Então, uma maneira de contornar que é trazer o objeto o objeto gerenciado contexto.
Aqui está o meu código (troquei as variáveis para fazer o trabalho para você):
// 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 isso ajude :)
Aqui, você está tentando estabelecer uma relação entre dois objetos que são buscados/criados com um contexto diferente. Os dados principais não permitem que você estabeleça essas relações. Para conseguir isso, você deve buscar o segundo objeto (você está tentando fazer um relacionamento) com o contexto do primeiro objeto com o ObjectId. Agora você deve ser capaz de estabelecer uma relação entre esses dois objetos. Por exemplo:
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 isso ajude você!
Como o erro diz, você não tem permissão para ter um relacionamento em um objeto de dados principal cujo valor é definido como outro objeto mantido em um contexto diferente. Uma maneira de contornar isso é esperar até que você salve o novo objeto e mesciá -lo de volta ao contexto primário e depois definir o owner
Relacionamento conforme apropriado (como ambos os objetos estão agora no mesmo contexto, não há problema com isso).
book *book = [mainContext ........] //Get book from default context
NSManagedObjectID *objectId = [book objectID];
Book *tmpBook = [tmpContext objectWithID:objectId]; //Now book has the legal relationship
Versão Swift ...
context.insert(objectFromOtherContext)