【问题标题】:One-to-Many Relationship: CoreData一对多关系:CoreData
【发布时间】:2014-07-19 18:26:13
【问题描述】:

我对 coredata 还很陌生,并且一直被困在一个问题上。 任何帮助将不胜感激。

信息: 我有一个带有实体的核心数据应用程序; 列表和任务。 List 和 Task 是一对多的关系。

任务.h

@class List;

@interface Task : NSManagedObject

@property (nonatomic, retain) NSString * task;
@property (nonatomic, retain) NSString * note;
@property (nonatomic, retain) List *list;

@end

列表.h

@class Task;

@interface List : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSDate * dateCreated;
@property (nonatomic, retain) NSNumber * sortOrder;
@property (nonatomic, retain) NSSet *task;
@end

@interface List (CoreDataGeneratedAccessors)

- (void)addTaskObject:(Task *)value;
- (void)removeTaskObject:(Task *)value;
- (void)addTask:(NSSet *)values;
- (void)removeTask:(NSSet *)values;

@end

我使用创建列表;

 NSManagedObjectContext *context = [self managedObjectContext];

if ([self.listTextField.text length] == 0) { // Quit here if no text is entered
    [self dismissViewControllerAnimated:YES completion:nil];
    return;
}

// Create a new list.
// Create an NSManagedObject for our database entity.
list = [NSEntityDescription insertNewObjectForEntityForName:@"List" inManagedObjectContext:context];
// Add the new task to the object (which in turns adds to our database).
[list setValue:self.listTextField.text forKey:@"name"];

// Get current date and time.
NSDate *todayDate = [NSDate date];
// Add the date to the object (which in turns adds to our database).
[list setValue:todayDate forKey:@"dateCreated"];


NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];

我可以使用下面的代码和 cellaccessorybuttontapped 更新已经创建的列表;

NSManagedObjectContext *context = [self managedObjectContext];

if ([self.listTextField.text length] == 0) {
    // Delete object from database.
    [context deleteObject:self.list];
    NSError *error = nil;
    // Save the action to persistent store
    if (![context save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
} else {
    // Update existing task.
    [self.list setValue:self.listTextField.text forKey:@"name"];
    // Get current date and time.
    NSDate *todayDate = [NSDate date];
    // Add the date to the object (which in turns adds to our database).
    [list setValue:todayDate forKey:@"dateCreated"];
    NSError *error = nil;
    // Save the action to persistent store
    if (![context save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    }
}
[self dismissViewControllerAnimated:YES completion:nil];

然后我可以导航到一个列表中。

我的问题是如何为刚刚导航到的列表创建任务? 已经 2 天了,我在 Google 上找不到任何东西。


根据建议,我已添加;

@property (strong, nonatomic) List *selectedList;

我现在有这个作为我的保存方法

NSManagedObjectContext *context = [self managedObjectContext];

// Saving a new task.
Task *task = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context];

task.task = self.taskText.text;
task.note = self.noteText.text;
task.list = self.selectedList;
NSLog(@"The selected list is: %@", [self.selectedList description]);

NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
[self.selectedList addTaskObject:task];
[self dismissViewControllerAnimated:YES completion:nil];

新任务已创建,但已在所有列表中创建。 有没有可能这是可行的,而我没有根据他们的列表获取任务?

这是我导航到列表时的获取请求:

if (fetchedResultsController != nil) {
    return fetchedResultsController;
}

// Create a fetch request.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Create an entity so fetch the data from.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
// Set the entity of the fetch request.
[fetchRequest setEntity:entity];
// Set the amount to be fetched at a time
[fetchRequest setFetchBatchSize:20];
// Create a sort descriptor.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"task" ascending:NO];
// Attach the sort descriptor to the fetch request.
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

// Create a fetch result controller using the fetch request
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                                              managedObjectContext:self.managedObjectContext
                                                                                                sectionNameKeyPath:nil
                                                                                                         cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
theFetchedResultsController.delegate = self;

// Perform fetch.
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    // Handle error.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    exit(-1);  // Fail
}
return fetchedResultsController;

【问题讨论】:

  • 移动 [self.selectedList addTaskObject:task];在此之前[上下文保存:&错误]。我也更新了我的答案。
  • 已实施,但任务仍添加到所有列表中。
  • 您将在任务实体中带来所有值。您需要获取与所选列表关联的值。可以简单到 [parentList.task allObjects];
  • 抱歉,我在哪里添加?

标签: ios core-data relationship


【解决方案1】:

这就是您的实体标头中的这些方法的用途:

- (void)addTaskObject:(Task *)value;
- (void)removeTaskObject:(Task *)value;
- (void)addTask:(NSSet *)values;
- (void)removeTask:(NSSet *)values;

您将创建一个新的任务实体:

Task *t = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context];

然后像处理列表对象一样填写其中的字段:

t.task = @"Whatever";
t.note = @"Whatever Note";
t.list = currentlySelectedListItem; // whatever that happens to be -- it will be a (List *)something

然后,您想将任务对象添加到列表中:

[currentlySelectedListItem addTask:t];

然后保存上下文,你就完成了。

这里的关键是您通过将任务添加到 NSSet 中包含的任务值集来有效地更新 List 对象。并且 t.list 将包含一个指向父 List 对象的指针。

在我看来你的布局很好(我假设:

@property (nonatomic, retain) List *list;

是与父列表的关系,而不仅仅是您定义的另一个值;看起来是这样)。

【讨论】:

  • 感谢您的帮助。不幸的是,我没有认可您的回答有帮助的声誉。
【解决方案2】:

您需要跟踪已导航到的列表。一种方法是创建一个名为parentList 的属性,就像这样

@property(nonatomic,strong) List *parentList

在视图控制器中创建任务。在导航到视图控制器之前设置此属性。

在任务视图控制器中,您使用Task *reqdTask = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context]; 执行类似于List 对象的插入,然后在按下Save 按钮后设置所有值。

[parentList addTaskObject: reqdTask];

你完成了。这将在任务实体中创建一个Task 并将其映射到List 实体。希望这会有所帮助。

**编辑***

您需要在保存上下文之前执行此操作[parentList addTaskObject: reqdTask];

将此添加到NSFectResultsController
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"list = %@",self.parentList]];

所以会是这样的

// Create a fetch request.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Create an entity so fetch the data from.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
// Set the entity of the fetch request.
[fetchRequest setEntity:entity];
// Set the amount to be fetched at a time
[fetchRequest setFetchBatchSize:20];
// Create a Predicate.
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"list = %@",self.parentList]];
//continue

这将带来与所选列表关联的任务。

【讨论】:

  • 太棒了。队友的欢呼声。真的很感激。标记为正确答案。
  • 没有问题..很高兴能提供一些帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多