Agregar nuevo atributo a la relación de entidad de datos centrales existente

No estoy seguro si mi comprensión de las relaciones de Core Data es errónea ya que no puedo lograr lo que quiero hacer.

Tengo 2 entidades creadas para administrar el chat en la aplicación y una relación de uno a muchos entre los usuarios y los posts. Entonces, un usuario puede tener muchos posts, pero los posts tienen solo usted usuario (creador).

introduzca la descripción de la imagen aquí

Estoy intentando actualizar la relación de la entidad ChatUser cuando se agrega un nuevo post mediante el cual se establece una connection entre la ID de ChatUser y el ChatMessage . Puedo hacer esto, pero el problema surge cuando voy a agregar un nuevo post a un userId existente. Sin embargo, todo lo que se está consiguiendo actualmente es agregar un userId adicional a userId en lugar de agregar solo la relación al UserId . De UserId existente.

 NSManagedObjectContext *context = [self managedObjectContext]; NSError *error = nil; // 4 . Get Timestamp for Rippll float timestamp = @([[NSDate date] timeIntervalSince1970]).floatValue; NSString * jayID = @"eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff"; NSString *message = @"Science string!"; // Create a new managed object ChatUser *chatUserManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context]; Chat *chatManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:context]; Timeline *timelineManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Timeline" inManagedObjectContext:context]; // 3 . Save Timeline [timelineManagedObject setEvent:chatEvent]; [timelineManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]]; [timelineManagedObject setMeta:@""]; [timelineManagedObject setViewed:@NO]; [timelineManagedObject setEventID:jayID]; //Save UserMessage [chatManagedObject setChatId:jayID]; [chatManagedObject setTimestamp:[NSNumber numberWithFloat:timestamp]]; [chatManagedObject setMessage:message]; [chatManagedObject setMedia:@""]; //Check if value exists NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"]; [request setPnetworkingicate:[NSPnetworkingicate pnetworkingicateWithFormat:@"userId = %@", jayID]]; [request setFetchLimit:1]; NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy]; if (entities.count == 0) { NSLog(@"GOOD TO ADD"); // no matching object [chatUserManagedObject setUserId:jayID]; //Create Relationship [chatUserManagedObject addChatObject:chatManagedObject]; } else { NSLog(@"IT EXISTS!"); [chatManagedObject setChat:chatUserManagedObject]; } // Save the object to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); } 

Adelgazé k, @PangHoMing estaba en el path correcto, pero usé Magical Records. Hagámoslo únicamente con CD:

Primero cambia el nombre de las relaciones. Probablemente, en ChatMessage debería haber una relación de 1 a 1 llamada user (o chatUser ) y en ChatUser debería haber un to-N relación de messages (o chatMessages ). Deben ser una relación inversa.

A continuación, debe solicitar la existencia de un usuario antes de crearlo. (De lo contrario, creará usuarios fantasmas). Obtuvo el código para ello:

 // Create message as you did ChatMessage *message = …; … // The user will go here ChatUser *user; // Do not use types in names unless conversion is subject of your code // Look for an existing one NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"]; [request setPnetworkingicate:[NSPnetworkingicate pnetworkingicateWithFormat:@"userId = %@", jayID]]; [request setFetchLimit:1]; NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy]; if (entities.count == 0) { // Only if there is none, create one user = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context]; // Set-up user's properties … } else { // Use the existing one user = entities[0]; } [message setValue:user forKey:@"user"]; // message.user = user; 

Como lo mencionaron otros, la relación inversa es mantenida por el CD. Sin embargo, puede usar la relación inversa para agregar el post, si esto es más legible para usted:

 [[user mutableSetValueForKey:@"messages"] addObject:message]; // [user addMessagesObject:message] 

Esto mantendrá la relación "original" también.

Core Data gestionará automáticamente el otro extremo de la relación una vez que lo inicie desde cualquier dirección. Puede agregar a la colección de chat ChatMessage o establecer el chat ChatMessage con una instancia de un object de NSManagedObject de NSManagedObject y eso es todo lo que tiene que hacer. Tenga en count que este process no requiere que administre foreign keys, esa complejidad se extrae de usted. Todavía puede almacenar identificadores del lado del server si lo ayudan a interactuar con una API, pero no son necesarios para Core Data.

Recomendaría cambiar un extremo de la relación para que ambos no sean nombrados lo mismo. Considere actualizar la relación de ChatUser para ser messages o algo similar.

  1. Primero debe verificar si existe una entidad de ChatUser en su context. Simplemente tratando de get ChatUser con ese ID de usuario, si hay un retorno de ChatUser significa que ChatUser ya se ha creado; si devuelve nil, significa que no hay una entidad ChatUser con ese ID de usuario que se está creando.
  2. Para manejar 1: muchas relaciones, debe usar [message setChatUser: chatUser] en lugar de chatUser addMessageObject

No dude en hacer cualquier pregunta de seguimiento si tiene alguna. ¡Aclamaciones!

Intenta implementar algo como este. Esta solución es casi la misma que la propuesta por Amin Negm-Awad

 NSManagedObjectContext *context = [self managedObjectContext]; NSError *error = nil; // 4 . Get Timestamp for Rippll NSString * jayID = @"eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff"; NSString *message = @"Science string!"; //Check if value exists NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ChatUser"]; [request setPnetworkingicate:[NSPnetworkingicate pnetworkingicateWithFormat:@"userId = %@", jayID]]; [request setFetchLimit:1]; NSArray *entities = [[context executeFetchRequest:request error:&error] mutableCopy]; ChatUser *chatUserManagedObject = nil; if (entities.count) { NSLog(@"IT EXISTS!"); chatUserManagedObject = entities.firstObject; } else { NSLog(@"GOOD TO ADD"); chatUserManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatUser" inManagedObjectContext:context]; [chatUserManagedObject setUserId:jayID]; } // Create a new managed object Chat *chatManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:context]; //Save UserMessage [chatManagedObject setChatId:jayID]; [chatManagedObject setTimestamp:[NSDate date]]; [chatManagedObject setMessage:message]; [chatManagedObject setMedia:@""]; [chatUserManagedObject addChatObject:chatManagedObject]; // Save the object to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); }