向现有核心数据实体关系添加新属性

Add new attribute to existing Core Data Entity Relationship

我不确定我对核心数据关系的理解是否有缺陷,因为我似乎无法实现我想做的事情。

我创建了 2 个实体来管理应用程序上的聊天以及用户和消息之间的一对多关系。所以一个用户可以有很多消息,但消息只有你用户(创建者)。

我正在尝试在添加新消息时更新 ChatUser 实体关系,从而在 ChatUser ID 和 ChatMessage 之间建立连接。我可以这样做,但是当我向现有 userId 添加新消息时出现问题。目前正在实现的是在 ChatUser 中添加一个额外的 userId,而不是仅添加与现有 UserId.

的关系
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 setPredicate:[NSPredicate predicateWithFormat:@"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]);
}
  1. 您应该首先检查您的上下文中是否已经存在 ChatUser 实体。只需尝试获取具有该用户 ID 的 ChatUser,如果有 ChatUser return,则意味着 ChatUser 已被创建;如果它 return 为 nil,则表示没有正在创建该用户 ID 的 ChatUser 实体。
  2. 要处理 1-many 关系,您应该使用 [message setChatUser:chatUser] 而不是 chatUser addMessageObject

如有任何后续问题,请随时提出。干杯!

一旦您从任一方向启动关系,Core Data 将自动管理关系的另一端。您可以添加到 ChatUserchat 集合或使用 NSManagedObject 的实例设置 ChatMessagechat,这就是您所要做的。请注意,此过程不需要您管理外键,复杂性已从您那里抽象出来。如果服务器端 ID 可以帮助您与 API 交互,您仍然可以存储服务器端 ID,但 Core Data 不需要它们。

我建议更改关系的一端,这样两者就不会被命名为同一事物。考虑将 ChatUser 的关系更新为 messages 或类似的关系。

我觉得k,@PangHoMing走对了路,但是用的是Magical Records。让我们只用 CD​​ 来做:

首先重命名关系。可能在 ChatMessage 中应该有一个名为 user(或 chatUser)的 to-1 关系,在 ChatUser 中应该有一个 to-N 关系 messages(或 chatMessages)。他们应该是反比关系。

接下来您应该在创建用户之前询问用户是否存在。 (否则你会创建幻影用户。)你得到了它的代码:

// 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 setPredicate:[NSPredicate predicateWithFormat:@"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;

正如其他人所说,反向关系是由CD维持的。但是,您可以使用反向关系来添加消息,如果这对您来说更具可读性:

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

这也将维持 "original" 关系。

尝试实现类似这样的东西。这个方案和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 setPredicate:[NSPredicate predicateWithFormat:@"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]);
}