Каков наилучший способ построить сложный NSCompoundPredicate? - PullRequest
10 голосов
/ 18 октября 2010

Мне нужно построить NSPredicate с большим количеством данных. Например, в SQL я бы сделал что-то вроде следующего:

SELECT * 
  FROM TRANSACTIONS
  WHERE CATEGORY IN (categoryList)
    AND LOCATION IN (locationList)
    AND TYPE IN (typeList)
    AND NOTE contains[cd] "some text"
    AND DATE >= fromDate
    AND DATE <+ toDate

Я борюсь с тем, как создать его как NSPredicate для использования с Core Data. Я прочитал документацию ... которая дает только упрощенные примеры. Если кто-нибудь может указать мне на более сложный пример, я, безусловно, был бы признателен за это.


Ну, у меня был ответ здесь в течение двух лет, который многие нашли полезным. Мой пост был удален. Вот обновленный URL с решением.

https://www.radeeccles.com/convert-sql-statement-to-an-nspredicate-for-use-with-core-data/

1 Ответ

9 голосов
/ 13 марта 2013

Что вам нужно сделать, это создать предикат для каждого из ваших предложений. Например, давайте разберем ваш запрос:

  1. ВЫБРАТЬ * ИЗ СДЕЛКИ
  2. ГДЕ КАТЕГОРИЯ В (список категорий)
  3. И РАСПОЛОЖЕНИЕ В (locationList)
  4. И TYPE IN (typeList)
  5. И NOTE содержит [cd] «некоторый текст»
  6. AND DATE> = fromDate AND DATE <+ toDate </li>

Исходя из этого, у вас есть 5 предикатов (2-6). Так что давайте работать над ними один за другим.

 NSPredicate *inCategoryPredicate = [NSPredicate predicateWithFormat:@"Category IN %@", categoryList];

 NSPredicate *locationPredicate = [NSPredicate predicateWithFormat:@"Location IN %@", locationList];

 NSPredicate *typePredicate = [NSPredicate predicateWithFormat:@"Type IN %@", typeList];

 NSPredicate *notePredicate = [NSPredicate predicateWithFormat:@"Note contains[c] %@", @"Some Text"];

 NSPredicate *startDatePredicate = [NSPredicate predicateWithFormat:@"Date => @", fromDate];

 NSPredicate *endDatePredicate = [NSPredicate predicateWithFormat:@"Date <= @", toDate];

Теперь вам просто нужно объединить их в один предикат: Документация Apple гласит :

Вы должны структурировать составные предикаты, чтобы минимизировать количество работа сделана. В частности, сопоставление регулярных выражений является дорогостоящим операция. Поэтому в составном предикате вы должны выполнить простые тесты перед регулярным выражением;

Как говорится, тогда вы должны сначала начать с "простых" предикатов. Итак:

NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: startDatePredicate, endDatePredicate, inCategoryPredicate, locationPredicate, typePredicate, notePredicate];

Вы всегда можете получить представление о том, как выглядит предикат (sql where), если вы NSLog его.

...