Основні дані какао - ефективний спосіб підрахунку юридичних осіб


174

Я багато читав про основні дані .. але який ефективний спосіб зробити підрахунок за Entity-Type (як, наприклад, SQL може зробити SELECT count (1) ...). Тепер я просто вирішив цю задачу, вибравши всі NSFetchedResultsControllerта отримав підрахунок NSArray! Я впевнений, що це не найкращий спосіб ...

Відповіді:


303

Я не знаю, чи використання NSFetchedResultsController є найбільш ефективним способом досягнення вашої мети (але це може бути). Явний код для отримання кількості екземплярів сутності нижче:

// assuming NSManagedObjectContext *moc

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:moc]];

[request setIncludesSubentities:NO]; //Omit subentities. Default is YES (i.e. include subentities)

NSError *err;
NSUInteger count = [moc countForFetchRequest:request error:&err];
if(count == NSNotFound) {
  //Handle error
}

[request release];

1
На Leopard ви хочете використовувати countForFetchRequest: а не виконуватиFetchRequest:
IlDan

І пропустіть, щоб встановити присудок. Немає присудка:
знайдіть

4
Просто FYI, count == 0, якщо для конкретного запиту немає результатів, NSNotFound = NSIntegerMax, тому "// помилка Генделя" не буде виконана, якщо результатів не буде.
Намір

Чи друкується помилка: setIncludesSubentities? Я думаю, що документація вказує нижній регістр "e" у "сутностях", а не верхній регістр "E" у прикладі коду.
Майк

2
@LarsSchneider документація для countForFetchRequest:error:станів, яка NSNotFoundповертається у разі помилки. Взагалі, NSErrorв Конвенції про какао поводження полягає в тому, що значення errне визначене (і часто небезпечне), якщо не виникає помилок.
Barry Wark

61

Щоб було зрозуміло, ви рахуєте не сутність, а екземпляри певної сутності. (Щоб буквально підрахувати сутності, попросіть керовану модель об'єкта про кількість її об'єктів.)

Для підрахунку всіх примірників даної сутності, не отримуючи всіх даних, використовуйте -countForFetchRequest:.

Наприклад:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName: entityName inManagedObjectContext: context]];

NSError *error = nil;
NSUInteger count = [context countForFetchRequest: request error: &error];

[request release];

return count;

32

Швидкий

Отримати підрахунок загальної кількості примірників суб'єкта в Основних даних досить просто:

let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "MyEntity")
let count = context.countForFetchRequest(fetchRequest, error: nil)

Я перевірив це на тренажері з кількістю об'єктів 400 000+, і результат був досить швидким (хоча і не миттєвим).


23

Я просто додам це, щоб зробити його ще більш ефективним ... а тому, що його просто підрахунок, вам дійсно не потрібна якась властивість, і, звичайно, як один із наведених вище прикладів коду, вам також не потрібні суб-субстанції.

Отже, код повинен бути таким:

int entityCount = 0;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourEntity" inManagedObjectContext:_managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesPropertyValues:NO];
[fetchRequest setIncludesSubentities:NO];
NSError *error = nil;
NSUInteger count = [_managedObjectContext countForFetchRequest: fetchRequest error: &error];
if(error == nil){
    entityCount = count;
}

Сподіваюся, це допомагає.


10

Я вважаю, що найпростіший та найефективніший спосіб підрахунку об'єктів - це встановити NSFetchRequestтип результату NSCountResultTypeта виконати його NSManagedObjectContext countForFetchRequest:error:методом.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
fetchRequest.resultType = NSCountResultType;
NSError *fetchError = nil;
NSUInteger itemsCount = [managedObjectContext countForFetchRequest:fetchRequest error:&fetchError];
if (itemsCount == NSNotFound) {
    NSLog(@"Fetch error: %@", fetchError);
}

// use itemsCount

6

Я написав простий метод утиліти для Swift 3, щоб отримати кількість об'єктів.

static func fetchCountFor(entityName: String, predicate: NSPredicate, onMoc moc: NSManagedObjectContext) -> Int {

    var count: Int = 0

    moc.performAndWait {

        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
        fetchRequest.predicate = predicate
        fetchRequest.resultType = NSFetchRequestResultType.countResultType

        do {
            count = try moc.count(for: fetchRequest)
        } catch {
            //Assert or handle exception gracefully
        }

    }

    return count
}

3

У Swift 3

  static func getProductCount() -> Int {
    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")
    let count = try! moc.count(for: fetchRequest)
    return count
}

1

Це дійсно просто так:

let kBoat = try? yourContainer.viewContext.count(for: NSFetchRequest(entityName: "Boat"))

"Човен" - це лише назва об'єкта на екрані вашої моделі даних:

введіть тут опис зображення

Що таке глобальне yourContainer?

Щоб користуватися основними даними, у якийсь момент програми, лише один раз, ви просто переходите

var yourContainer = NSPersistentContainer(name: "stuff")

де "stuff" - це просто назва файлу моделі даних.

введіть тут опис зображення

Ви просто отримаєте для цього сингл,

import CoreData
public let core = Core.shared
public final class Core {
    static let shared = Core()
    var container: NSPersistentContainer!
    private init() {
        container = NSPersistentContainer(name: "stuff")
        container.loadPersistentStores { storeDescription, error in
            if let error = error { print("Error loading... \(error)") }
        }
    }
    
    func saveContext() {
        if container.viewContext.hasChanges {
            do { try container.viewContext.save()
            } catch { print("Error saving... \(error)") }
        }
    }
}

Так з будь-якого місця в додатку

core.container

ваш контейнер,

Тож на практиці отримувати підрахунок будь-якої сутності, це просто

let k = try? core.container.viewContext.count(for: NSFetchRequest(entityName: "Boat"))

0

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

NSError *err;
NSUInteger count = [context countForFetchRequest:fetch error:&err];

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.