2016-04-19 6 views
2

Ich versuche, eine SUBQUERY für ein NSPredikat zu schreiben. Mein Problem ist, dass ich die Abfrage für den Prädikatanteil der SUBQUERY nicht zur Hand habe. Gibt es eine Möglichkeit, ein NSPredate in der SUBQUERY zu verschachteln?NSPredate innerhalb einer SUBQUERY

Zum Beispiel das ist, was ich versucht habe:

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) 

Update: Ich hatte jetzt eine schmutzige Abhilfe zu tun, indem sie das erste Prädikat ausführen und ein ANY IN-Abfrage zu tun. Sein lahm :(, weil ich die ordersPredicate auch anderswo später in der Pipeline Ausführung ..

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

könnten Sie Ihre Order-Klasse/definition posten und erklären, was Sie erreichen wollen? – vikingosegundo

+0

im Abhilfe Sie eine Unterabfrage nicht benötigen, 'keine Aufträge in% @' tun wird. W hy setzen Sie 'returnObjectsAsFaults' auf false? – Willeke

+0

Wenn Sie ein Prädikat in einer Unterabfrage verwenden möchten, sollte das Prädikat etwas wie '$ x.orderNumber = 10', mit' $ x' sein. Es ist möglich, das Prädikat zu konvertieren, aber es ist möglicherweise einfacher, die Pipeline neu zu entwerfen. – Willeke

Antwort

2

Dank einiger Zeiger von @Willeke konnte ich mit einer Lösung kommen.

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 "||" 
     } 
    } 
} 

und hier ist die Nutzung

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