Незаконная попытка установить связь 'xyz' между объектами в разных контекстах - PullRequest
42 голосов
/ 12 октября 2009

Я использую образец приложения Apple CoreDataBooks в качестве основы для извлечения данных в фоновый контекст вторичного управляемого объекта и последующего слияния этих данных в контекст первичного управляемого объекта.

Данные, которые я извлекаю, это Book сущность с отношением один к одному с Owner сущностью (называемой "владельцем") Сущность Owner имеет отношение ко-многим с Book (называемыми "книгами").

Мои данные представляют собой XML-документ в форме:

<Owner>
  <Name>alexpreynolds</Name>
  <ID>123456</ID>
</Owner>
<Books>
  <Book>Book One</Book>
  <Book>Book Two</Book>
  ...   
  <Book>Book N</Book>
</Books>

Book One - Book N связаны с одним Owner ("alexpreynolds, 123456").

Я анализирую это в Owner экземпляр и NSMutableSet, состоящий из Book экземпляров.

Когда я пытаюсь сохранить в первый раз, он сохраняется нормально, и объединенные данные отображаются в табличном представлении.

Однако при втором сохранении, когда содержимое XML содержит новую книгу, оно не работает.

Вот что происходит:

Затем я пытаюсь загрузить XML-документ, который содержит новый Book, которого еще нет в контексте основного управляемого объекта. Новый Book использует тот же Owner, что и тот, который связан с другими Book с.

У меня есть подпрограммы, которые выбирают этот уникальный Owner управляемый объект (который у меня уже есть в контексте моего основного управляемого объекта) и уникальный Book, который не найден в первичном MOC.

Исходя из этого, я создаю новый объект Book во вторичном MOC и устанавливаю его отношение "owner", чтобы указать на уникальный Owner, найденный в первичном MOC.

Когда я сохраняю, я получаю следующую ошибку:

*** 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;
}))'

Как мне создать новую сущность Book во вторичном MOC, чтобы я все еще мог связать ее с уже существующим Owner в первичном MOC?

Ответы [ 6 ]

67 голосов
/ 12 октября 2009

Нельзя иметь отношения между объектами в разных контекстах управляемого объекта. Поэтому один из способов обойти это - перевести объект в контекст управляемого объекта.

Например:

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]]];

Итак, вы на самом деле извлекаете Book в тот же контекст управляемого объекта с owner. Имейте в виду, однако, что это возможно только в том случае, если book уже был сохранен. Контекст управляемого объекта будет искать объект в постоянном хранилище, поэтому его нужно сначала сохранить.

9 голосов
/ 25 февраля 2013

У меня была та же проблема, и это предложение помогло мне решить ошибку.

Нельзя иметь отношения между объектами в разных управляемых контексты объекта. Таким образом, один из способов обойти это, чтобы принести объект в контекст управляемого объекта.

Вот мой код (я заменил переменные, чтобы он работал для вас):

// 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];

Надеюсь, это поможет:)

4 голосов
/ 18 апреля 2016

Здесь вы пытаетесь установить связь между двумя объектами, которые извлекаются / создаются в другом контексте. Основные данные не позволят вам установить такие отношения. Чтобы достичь этого, вы должны получить второй объект (с которым вы пытаетесь установить связь) с контекстом первого объекта с objectID. Теперь вы сможете установить связь между этими двумя объектами. Например:

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
})

Надеюсь, это поможет вам!

1 голос
/ 12 октября 2009

Как говорится в сообщении об ошибке, вам не разрешено иметь отношения в одном объекте Core Data, значение которого установлено для другого объекта, содержащегося в другом контексте. Один из способов обойти это - подождать до тех пор, пока вы не сохраните новый объект и не объедините его обратно с основным контекстом, а затем установить подходящее отношение owner (поскольку оба объекта теперь находятся в одном контексте, проблем с что).

0 голосов
/ 01 июня 2018

Swift версия ...

context.insert(objectFromOtherContext)
0 голосов
/ 18 апреля 2016
book *book = [mainContext ........]   //Get book from default context

NSManagedObjectID *objectId = [book objectID];

Book *tmpBook = [tmpContext objectWithID:objectId]; //Now book has the legal relationship
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...