开发者

What is the best way to build a complex NSCompoundPredicate?

I need to build an NSPredicate with many pieces of data. For example in SQL I would do something like the 开发者_StackOverflowfollowing:

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

I'm struggling with how to build this as an NSPredicate for use with Core Data. I've read the documentation... which only provides simplistic examples. If anybody can point me to a more complex example I would certainly appreciate it.


Well, I had an answer out here for two years that many people found helpful. My post was deleted. Here is the updated URL with the solution.

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


What you need to do is to create a Predicate for each one of your clauses. For example let's break down your query:

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

Based on this, you have 5 predicates (2-6). So let's work on them one by one.

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

Now you just need to join them into just one predicate: Apple's documentation states:

You should structure compound predicates to minimize the amount of work done. Regular expression matching in particular is an expensive operation. In a compound predicate, you should therefore perform simple tests before a regular expression;

This being said then you should start with the "easy" predicates first. So:

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

You can always get an idea of what the predicate (sql where) looks like if you NSLog it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜