使用核心数据更新对象会插入新记录

问题描述 投票:0回答:3

我正在尝试更新核心数据中的记录,但实际上是在插入新记录。以下代码用于解锁我的游戏的下一个级别。

- (void)unlockNextLevel
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *levelEntity = [NSEntityDescription entityForName:@"Level"
                                                   inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:levelEntity];

    int nextLevelPosition = [self.position intValue] + 1;

    NSPredicate *predicate = [NSPredicate predicateWithFormat:
                              [NSString stringWithFormat:@"position == %i",
                               nextLevelPosition]];
    [fetchRequest setPredicate:predicate];

    NSError *error;

    NSArray *result = [[self managedObjectContext] executeFetchRequest:fetchRequest
                                                                          error:&error];

    if (error) {
        NSLog(@"%@", error.description);
    }

    if (result.count > 0) {
        Level *nextLevel = result[0];

        nextLevel.locked = [NSNumber numberWithBool:NO];

        [self saveContext];
    }
}

在这里,我通过它的位置取一个对象,它应该是唯一的(按照惯例),然后改变它的“锁定”属性。我期待它更新,但核心数据正在插入新记录......

我正在更新的对象与它所属的世界有关系。所以一个世界有很多级别,一个级别只有一个世界。

我认为值得一提的是,插入SQLite的记录没有引用世界(世界的id为null)。

希望您能够帮助我。

ios sqlite core-data
3个回答
1
投票

以下行是创建新“级别”实体的位置。

NSEntityDescription *levelEntity = [NSEntityDescription entityForName:@"Level"
                                               inManagedObjectContext:[self managedObjectContext]];

我想您可以使用以下代码初始化获取请求:

NSFetchRequest *req = [[NSFetchRequest alloc] initWithEntityName:@"Level"];

并删除以下行:

 [fetchRequest setEntity:levelEntity];

2
投票

更新核心数据实体swift 4中的记录

    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let context = appDelegate.persistentContainer.viewContext

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")

    request.predicate = NSPredicate(format: "age = %@ AND username = %@",self.dictData[0].value(forKey: "age") as! CVarArg,self.dictData[0].value(forKey: "username") as! CVarArg)

    do {

        let result = try context.fetch(request)

        let objUpdate = result[0] as! NSManagedObject

        let strUN = txtFldUserName.text!
        let strPassword = txtFldPassword.text!
        let strAge = txtFldAge.text!

        // put all entity field
        objUpdate.setValue(strUN, forKey: "username")
        objUpdate.setValue(strPassword, forKey: "password")
        objUpdate.setValue(strAge, forKey: "age")

        print("update success!")
        try context.save()

    } catch {
        print("Failed")
    }

希望这有帮助!


0
投票

试试这种方式。首先使用像articleID这样的唯一属性值来获取所需的实体。如果您将实体作为nil,则创建新的实体实例或者更新它。

Entity * entityInstance = nil;
 entityInstance = [self fetchEntityForID:entityInstanceID inContext:context];

 if (entityInstance == nil) 
{
 entityInstance = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:context];
}

-(Entity *)fetchEntityForID:(NSNumber *) articleID inContext:(NSManagedObjectContext *) writeContext
{
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Entity"];
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"articleID == %@",articleID];
    [fetchRequest setPredicate:predicate];

    NSArray *fetchedArray = [writeContext executeFetchRequest:fetchRequest error:nil];
    if ([fetchedArray count] > 0) {
        return [fetchedArray objectAtIndex:0];
    }
    return nil;
}

希望能帮助到你 :)

© www.soinside.com 2019 - 2024. All rights reserved.