如何在一对多核心数据关系中获取特定数据?

时间:2016-12-30 04:27:47

标签: ios objective-c core-data

我已经就核心数据关系做了一个示例演示。我有一个表" User"这是另一张表"帐号"以"一对多的形式"关系。

代码

-(IBAction)savePersonData:(id)sender
{

    NSManagedObjectContext *context = appDelegate.managedObjectContext;

    NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    [newDevice setValue:self.personName.text forKey:@"name"];
    [newDevice setValue:self.personAddress.text forKey:@"address"];
    [newDevice setValue:self.personMobileNo.text forKey:@"mobile_no"];


    NSManagedObject *newAccount = [NSEntityDescription insertNewObjectForEntityForName:@"Account" inManagedObjectContext:context];
    [newAccount setValue:self.accountNo.text forKey:@"acc_no"];
    [newAccount setValue:self.accountType.text forKey:@"acc_type"];
    [newAccount setValue:self.balance.text forKey:@"balance"];

    NSLog(@"Saved Successfully");
    [self dismissViewControllerAnimated:YES completion:nil];

}

图片是

我的问题是

我找到了这么多时间,却找不到合适的答案。所以我第二次发布这个问题。

我的问题是我已经手动插入了三个人的帐户详情。

现在,我想要在输入手机号码时为特定的人输入的余额。

实施例

1)输入1st Mobile Num。应该显示第一个人的余额。 2)输入2nd Mobile Num。应显示第二人的余额。 1)输入3rd Mobile Num。应显示第三人的余额。

余额检查代码

-(IBAction)checkBalance:(id)sender

{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"mobile_no = %@",self.textField.text];

    [fetchRequest setPredicate:predicate];
    NSError *error;
    NSArray *result = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if(!([result count] == 0))
    {        

        NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
        NSFetchRequest *newFetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Account"];
        NSMutableArray *temp = [[managedObjectContext executeFetchRequest:newFetchRequest error:nil] mutableCopy];

        for (NSManagedObject *object in temp)
        {
            NSString *intValue = [object valueForKey:@"balance"];
            NSString *alertString = [NSString stringWithFormat:@"%@",intValue];
            [self displayAlertView:@"Available Balance" withMessage:alertString];
        }
    }
    else
    {
        [self displayAlertView:@"Error" withMessage:@"Please Enter Valid Mobile Number That you have entered in Bank"];
    }
}

图片

enter image description here

输出

enter image description here enter image description here

我希望在TextField上输入Person Mobile No的特定人员余额。

抱歉,伙计们,我第二次问过,但无法解决这个核心数据关系。

谢谢。

1 个答案:

答案 0 :(得分:2)

<强>首先...

修复关系的命名。正如其他人在对您的其他问题的评论中指出的那样,您已将它们命名为前置:在Person实体中,与Account的多对多关系应命名为“帐户”而不是“人” 。同样在Account实体中,与Person的一对一关系应命名为“人”而不是“帐户”。

下一步...

虽然您已将“帐户”关系定义为多个,但此问题中的savePersonData代码仅创建一个Account和一个Person - 但不会设置关系它们之间。 (您可以在输出中看到这一点:每个Account的“帐户”关系都为零。

上一个问题中的代码确实设置了关系(通过将newAccount添加到newPerson对象上的关系)。在上面的代码中,您可以使用(在修复关系名称之后):

NSMutableSet *setContainer = [newDevice mutableSetValueForKey:@"accounts"];
[setContainer addObject:newAccount];

但是通过一对多的关系,可以更容易地设置反比关系:

[newAccount setValue:newDevice forKey:@"person"];

下一步...

您的checkBalance方法正确提取其“mobile_no”属性匹配的任何Person个对象。但是,随后的代码会提取所有Account个对象 - 即使您已正确设置关系。

如果您只想要与给定Account相关的Person个对象,那么这正是“帐户”关系所代表的内容。因此,您可以使用该关系来访问相关的Account对象:

if(!([result count] == 0)) {
    NSManagedObject *requiredPerson = (NSManagedObject *)result[0];
    NSSet *temp = [requiredPerson valueForKey:@"accounts"];
    for (NSManagedObject *object in temp) {
        NSString *intValue = [object valueForKey:@"balance"];
        NSString *alertString = [NSString stringWithFormat:@"%@",intValue];
        [self displayAlertView:@"Available Balance" withMessage:alertString];
    }
}

或者,通过指定遍历关系的谓词,直接获取相关的Account对象(不首先获取Person对象):

NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *newFetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Account"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person.mobile_no = %@",self.textField.text];
[newFetchRequest setPredicate:predicate];

NSMutableArray *temp = [[managedObjectContext executeFetchRequest:newFetchRequest error:nil] mutableCopy];

    for (NSManagedObject *object in temp)
    {
        NSString *intValue = [object valueForKey:@"balance"];
        NSString *alertString = [NSString stringWithFormat:@"%@",intValue];
        [self displayAlertView:@"Available Balance" withMessage:alertString];
    }