Удаление определенной записи / строки из Core-Data - PullRequest
23 голосов
/ 29 июня 2011

Я использую основные данные в своем приложении, и я запутался, когда речь идет об удалении определенных строк или записей из основного хранилища данных. Я вставляю некоторые продукты в хранилище так:

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'

Я был бы очень признателен за пример кода, так как не могу понять это.

Спасибо за любую помощь.

Ответы [ 8 ]

42 голосов
/ 30 июня 2011

Как сказал @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. Обратите внимание, что предикат логически выполняет ту же функцию, что и предложение where в SQL.

Когда у вас есть объекты, вы просто указываете контексту, чтобы удалить их:

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

При следующем сохранении контекста данные объекта будут удалены из файла постоянного хранения.

13 голосов
/ 20 мая 2014

Как и в случае Sqlite «УДАЛИТЬ из условия tableName WHERE», у вас нет одного шага для удаления MULTIPLE объектов из CoreData.

В CoreData сначала необходимо извлечь объектов, которые необходимо удалить, используя NSFetchRequest и NSPredicate

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 и позвонить deleteObject: со своего NSManagedObjectContext.

if (!error && result.count > 0) {
    for(NSManagedObject *managedObject in result){
        [managedObjectContext deleteObject:managedObject];
    }

    //Save context to write to store
    [managedObjectContext save:nil];
}
6 голосов
/ 23 января 2013

Используйте этот метод:

+ (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];
}
6 голосов
/ 29 июня 2011

Не забывайте думать о базовых данных как о графике, а не как о БД, поэтому концепция строк не применяется. Вместо этого вы хотите удалить конкретный объект из графика.

Вы использовали insertNewObjectForEntityForName:inManagedObjectContext:, чтобы вставить его. Используйте deleteObject:, чтобы удалить его, например:

[aContext deleteObject:aManagedObject];

В вашем случае

[context deleteObject:Product];

Удачи

См. Объяснение Apple здесь

Примечание: при удалении, в зависимости от вашей схемы, это может иметь разные последствия. Например, он может удалить все дальше по дочернему пути вашего графа объекта Core Data. Убедитесь, что вы тщательно продумали при разработке схемы, как это должно работать. Если вы все настроите правильно, это может стать для вас огромным преимуществом.

2 голосов
/ 16 мая 2012

используйте это

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];
1 голос
/ 03 июня 2016

Я работаю с UITableView для удаления в течение нескольких дней, в конце концов, я все сделал.

Представление таблицы заполняется данными из основного объекта данных.Использовались следующие методы делегирования:

-(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];
}

Надеюсь, кто-нибудь поможет.

0 голосов
/ 17 апреля 2017

В 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{

                }
            }
0 голосов
/ 30 октября 2013

Довольно просто, где 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]    

}
...