【问题标题】:Removing a specific entry/row from Core-Data从核心数据中删除特定条目/行
【发布时间】:2011-09-25 09:01:15
【问题描述】:

我在我的应用程序中使用核心数据,但在从核心数据存储中删除某些行或条目时我感到很困惑。我将一些产品插入到存储中,如下所示:

NSManagedObject *Product = [NSEntityDescription insertNewObjectForEntityForName:@"Product" inManagedObjectContext:context];
[Product setValue:[NSNumber numberWithFloat:id] forKey:@"pid"];
[Product setValue:[NSNumber numberWithFloat:quantity] forKey:@"pquantity"];

这适用于插入。但是,稍后在应用程序中,我想删除例如 pid 为 53 的条目。我将如何只删除此行/条目?等效的 SQL 类似于:

DELETE from Product WHERE pid = '53'

我将非常感谢一些示例代码,因为我似乎无法弄清楚这一点。

感谢您的帮助。

【问题讨论】:

    标签: iphone objective-c xcode core-data nsmanagedobject


    【解决方案1】:

    在 Swift 3 中:

             if let dataAppDelegatde = UIApplication.shared.delegate as? AppDelegate {
    
    
                    let mngdCntxt = dataAppDelegatde.persistentContainer.viewContext
    
                    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ItemCart")
    
                    let predicate = NSPredicate(format: "itemId = %i", Int(currentItemID)!)
                    print(currentItemID)
    
                    fetchRequest.predicate = predicate
                    do{
                        let result = try mngdCntxt.fetch(fetchRequest)
    
                        print(result.count)
    
                        if result.count > 0{
                            for object in result {
                                print(object)
                                mngdCntxt.delete(object as! NSManagedObject)
                            }
                        }
                    }catch{
    
                    }
                }
    

    【讨论】:

    • 此代码不会删除该行,而是使currentItemId = 0。我正在搜索删除该行。
    【解决方案2】:

    我一直在使用 UITableView 滑动删除几天,最终我完成了工作。

    tableview 由来自核心数据对象的数据填充。已使用的委托方法有:

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSectin:(NSInteger)section**
    {
       reture [_arrData count];
    }
    
    -(NSInteger)numberOfSectionInTablesView:(UITableView *)tableView
    {
      return 1;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
      static NSString *cellID = @"Cell";
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
      if(cell == nil){
         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStleDefault reuseIdentifier:cellID];
      }
      cell.textLable.text = [_arrData objectAtIndex:indexPath.row];
      return cell;
    }
    
    -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
      return YES;
    }
    
    -(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
        UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action,NSIndexPath *indexPath){
    
    
            //**************load address **************
            NSError *error;
    
            AppDelegate *sharedDelegate = [AppDelegate appDelegate];
            NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
    
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"data" inManagedObjectContext:context];
    
            NSFetchRequest *fetchReuqets = [[NSFetchRequest alloc] init];
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"lat == %@", [_arrLat objectAtIndex:indexPath.row]];
            [fetchReuqets setPredicate:predicate];
    
            NSLog(@"delete %@",[_arrLat objectAtIndex:indexPath.row]);
    
            [fetchReuqets setEntity:entity];
            NSArray *fetchedObjects = [context executeFetchRequest:fetchReuqets error:&error];
            NSLog(@"number of filtered objects=%ld",fetchedObjects.count);
            if(!error && fetchedObjects.count>0){
                for (NSManagedObject *addr in fetchedObjects){
                    [context deleteObject:addr];
                    NSLog(@"delete addr %@",addr);
                }
                [context save:&error];
            }
            //***************core data**************************
            [_arrData removeObjectAtIndex:indexPath.row];
            [tableView reloadData];
    
        }];
        delete.backgroundColor = [UIColor redColor];
        return @[delete];
    }
    

    希望能帮助别人。

    【讨论】:

      【解决方案3】:

      使用这个方法:

      + (void)Deletebeer:(NSString*)m_Beerid
      {
          AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
          NSManagedObjectContext *context = [appDelegate managedObjectContext];
      
          NSEntityDescription *productEntity=[NSEntityDescription entityForName:@"Beers" inManagedObjectContext:context];
          NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
          [fetch setEntity:productEntity];
          NSPredicate *p=[NSPredicate predicateWithFormat:@"m_Beerid == %@", m_Beerid];
          [fetch setPredicate:p];
          //... add sorts if you want them
          NSError *fetchError;
           NSError *error;
          NSArray *fetchedProducts=[context executeFetchRequest:fetch error:&fetchError];
          for (NSManagedObject *product in fetchedProducts) {
              [context deleteObject:product];
          }
          [context save:&error];
      }
      

      【讨论】:

        【解决方案4】:

        就像 Sqlite 的“DELETE from tableName WHERE 条件”一样,您没有一步可以从 CoreData 中删除 MULTIPLE 对象。

        CoreData 中,首先您必须使用NSFetchRequestNSPredicate获取 必须删除的对象

        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"EntityName"];
        
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"propertyName == %@", value];
        [request setPredicate:predicate];
        
        NSError *error = nil;
        NSManagedObjectContext *managedObjectContext;//Get your ManagedObjectContext;
        NSArray *result = [managedObjectContext executeFetchRequest:request error:&error];
        

        然后,您应该迭代遍历每个NSManagedObject 并从您的NSManagedObjectContext 调用deleteObject:

        if (!error && result.count > 0) {
            for(NSManagedObject *managedObject in result){
                [managedObjectContext deleteObject:managedObject];
            }
        
            //Save context to write to store
            [managedObjectContext save:nil];
        }
        

        【讨论】:

          【解决方案5】:

          非常简单,其中 DatabaseInfo 是我的实体的名称,其中 filename 是一个属性

          CoreAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
          
          NSManagedObjectContext *context = [appDelegate managedObjectContext];
          
          NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:context];
          
          NSFetchRequest *request = [[NSFetchRequest alloc] init];
          [request setEntity:entityDesc];
          
          NSPredicate *pred= [NSPredicate predicateWithFormat:@"(filename = %@)", @"Thankyou"];
          
          [request setPredicate:pred];
          NSManagedObject *matches = nil;
          
          NSError *error;
          NSArray *objects = [context executeFetchRequest:request error:&error];
          
          if([objects count] == 0)
          {
              _label1.text=@"No Match Found";
          }
          else{
              matches = objects[0];
          
              [context deleteObject:matches]    
          
          }
          

          【讨论】:

            【解决方案6】:

            使用这个

            Entity  *entity = (Entity *)[NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:managedObjectContext];
            [entity setTimeStamp:[NSDate date]];
            NSError *error;
            if ([managedObjectContext save:&error]) {
            
            }
            [eventArray delete:<#(id)sender#>];
            
            [self.tableView reloadData];
            

            【讨论】:

              【解决方案7】:

              请记住将 Core Data 视为图形而不是数据库,因此行的概念不适用。相反,您想从图表中删除特定对象。

              您使用insertNewObjectForEntityForName:inManagedObjectContext: 插入它。使用deleteObject:删除,如:

              [aContext deleteObject:aManagedObject];

              在你的情况下,

              [context deleteObject:Product];

              祝你好运

              查看 Apple 的 explanation here

              注意:根据您的方案,删除时可能会产生不同的影响。例如,它可以删除 Core Data 对象图的子路径下的所有内容。确保在设计架构时认真思考它应该如何工作。如果您设置正确,这对您来说可能是一个巨大的优势。

              【讨论】:

                【解决方案8】:

                正如@Nektarios 所说,您在这里处理对象,因此您想找到一个具有特定属性值的对象。你有一个获取请求和一个谓词。

                  NSNumber *soughtPid=[NSNumber numberWithInt:53];
                  NSEntityDescription *productEntity=[NSEntityDescription entityForName:@"Product" inManagedObjectContext:context];
                  NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
                  [fetch setEntity:productEntity];
                  NSPredicate *p=[NSPredicate predicateWithFormat:@"pid == %@", soughtPid];
                  [fetch setPredicate:p];
                  //... add sorts if you want them
                  NSError *fetchError;
                  NSArray *fetchedProducts=[self.moc executeFetchRequest:fetch error:&fetchError];
                  // handle error
                

                fetchedProducts 数组将包含实体Product 的所有对象,其pid 属性等于soughtPid。请注意,谓词在逻辑上与 SQL 中的where 子句实现相同的功能。

                一旦你有了对象,你只需告诉上下文删除它们:

                  for (NSManagedObject *product in fetchedProducts) {
                    [context deleteObject:product];
                  }
                

                下次保存上下文时,对象的数据将从持久存储文件中删除。

                【讨论】:

                • 我根据我的要求编辑了一些代码,但这段代码对我有用,谢谢@TechZen
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-09
                • 1970-01-01
                相关资源
                最近更新 更多