2016-04-19 35 views
2

我正在尝试为NSPredicate编写一个子查询。我的问题是我没有查询SUBQUERY的谓词部分。有没有办法在SUBQUERY内部嵌套一个NSPredicate?NSPredicate SUBQUERY内

例如这是我曾尝试:

let ordersPredicate = NSPredicate()//some predicate passed in 
//how do I use the ordersPredicate inside the subquery?? 
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x,'%@')[email protected] > 0", ordersPredicate.predicateFormat) 

更新:我已经通过执行第一个谓词和IN查询ANY做一个做一个肮脏的解决方法了。其跛脚:(因为我从@Willeke执行ordersPredicate其他地方以及后来在管道..

let fetchRequest = NSFetchRequest()//blah 
fetchRequest.predicate = orderPredicate 
let orders = //execute fetch 
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, ANY $x in %@)[email protected] > 0", orders) 
+0

你可以发布您的Order类/定义和解释你想达到什么? – vikingosegundo

+0

在解决方法你不需要一个子查询,在'%@任何订单'就行了。 w ^你是否将'returnObjectsAsFaults'设置为false? – Willeke

+0

如果你想在子查询中使用谓词,谓词应该是'$ x.orderNumber = 10',''x''。可以转换谓词,但可能更容易重新设计管线。 – Willeke

回答

2

由于一些指点,我能够拿出一个解决方案。

public extension NSPredicate{ 
    public func stringForSubQuery(prefix:String) -> String{ 
     var predicateString = "" 
     if let predicate = self as? NSCompoundPredicate{ 
      for (index, subPredicate) in predicate.subpredicates.enumerate(){ 

       if let subPredicate = subPredicate as? NSComparisonPredicate{ 
        predicateString = "\(predicateString) \(prefix)\(subPredicate.predicateFormat)" 
       } 
       else if let subPredicate = subPredicate as? NSCompoundPredicate{ 
        predicateString = "\(predicateString) (\(subPredicate.stringForSubQuery(prefix)))" 
       } 
       //if its not the last predicate then append the operator string 
       if index < predicate.subpredicates.count - 1 { 
        predicateString = "\(predicateString) \(getPredicateOperatorString(predicate.compoundPredicateType))" 
       } 
      } 
     } 
     return predicateString 
    } 
    private func getPredicateOperatorString(predicateType: NSCompoundPredicateType) -> String{ 
     switch(predicateType){ 
     case .NotPredicateType: return "!" 
     case .AndPredicateType: return "&&" 
     case .OrPredicateType: return "||" 
     } 
    } 
} 

这里是使用

let ordersPredicate = NSPredicate()//some predicate passed in 
let ordersPredicateFormat = orderPredicate.stringForSubQuery("$x.") 
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, \(ordersPredicateFormat))[email protected] > 0")