2011-08-22 64 views
0

由於數據庫結構有點複雜,我很難解決這個謂詞問題。我有以下的數據庫結構,或者至少是值得關注的一個問題:複雜的NSPredicate遍歷多個實體和關係類型

PUBLISHER < < --- >>公關< < --BOOK < < --->作者< < - >>代理

我試過以下謂詞,當我遍歷過去的關係時使用過,但沒有達到這個程度。我要指出,我有一個NSArray與代理商的名字,我想查詢對數據庫,以確定出版社代理的工作原理與列表:

NSArray *agentNames = [NSArray arrayWithObjects:Dan, Hunter, Sloan, Jackson]; 

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 

request.entity = [NSEntityDescription entityForName:@"Publisher" inManagedObjectContext:context]; 
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor 
      sortDescriptorWithKey:@"publisherName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] ]; 
request.predicate = [NSPredicate predicateWithFormat:@"ANY pubHouse.publicist.assignedBook.authorRep.agentName IN %@", [agentNames valueForKey:@"agentName"]]; 
request.fetchBatchSize = 20; 

    NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; 

當我運行前面的謂語我得到以下警告:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : ANY pubHouse.publicist.assignedBook.authorRep.agentName IN 

我相信,當我將書實體關係傳送到作者實體,然後到達代理實體時謂詞會中斷。在這一點上,建議會有所幫助。由於

+0

你的NSArray agentNames中有哪些變量? NSManagedObject的子類?字典? – Mundi

+0

您的實體之間的所有關係是否只是定期的舊關係,或者是關於它們的任何「特別」?另外,'authorRep.agentName'看起來有點好奇。 'agentName'真的是你作者代理關係的名字嗎?還是你的意思是像'authorRep.agent.agentName'? –

+0

這是從前一個視圖控制器傳遞的一個Agent對象數組,用戶可以選擇他們想要查詢的代理。我以前用這種方法取得了成功。我在這個問題中以這樣一種方式顯示了示例數組,以幫助那裏的優秀的撒瑪利亞人明白我想要完成的事情。感謝您付出的努力。 – dman

回答

6

你的問題是,謂詞解析器不知道應該應用什麼設置ANY

有了這個數據模型:

PUBLISHER<< --- >>PUBLICIST<<-->BOOK<<--->AUTHOR<<-->>AGENTS 

...您的keyPath:

pubHouse.publicist.assignedBook.authorRep.agentName 

...是以對象的形式,並設置的關係看起來像:

object.set.object.object.set 

所以,那就是ANY可以適用的兩套。

你可以嘗試建立一個子查詢來處理謂詞,但是如果你必須橫切那麼多的關係,你的獲取會涉及大量的數據,並且會非常非常緩慢(假設你能夠在第一個地方)。

通常當你最終得到這樣一個複雜的謂詞時,它表明你正在從錯誤的一端接近問題。在這種情況下,它會更容易從一個簡單的謂詞,如:

NSArray *agentNames = [NSArray arrayWithObjects:Dan, Hunter, Sloan, Jackson]; 
request.entity = [NSEntityDescription entityForName:@"Agent" inManagedObjectContext:context]; 
request.predicate = [NSPredicate predicateWithFormat:@"agentName IN %@", agentNames]; 

然後你會走關係的keyPath:

authors.books.publicist.publishers 

...找到所有相關的出版商。

無論你做什麼,我都認爲你會遇到麻煩,因爲有多個多對多的關係,例如

PUBLISHER<<--->>PUBLICIST 

...增加了謂詞和關係呈指數級走向的複雜性。通常,在這種情況下,您可能需要額外的實體來更深入地模擬其中一種關係。這通常會降低數據模型本身的複雜性,從而簡化了抓取和漫遊。

+0

你說得對。我試圖找到一個體面的解決方法,但我必須消除一些關係,並創建實體,以減少多對多關係的數量,以便通過關係。謝謝您的幫助 – dman

-1

只是包裝你的謂語字符串的IN子句中括號:

@"ANY (pubHouse.publicist.assignedBook.authorRep.agentName IN %@)" 

會很高興知道,如果它的工作原理。

+0

-1不行,那不行。 –

0

也許NSArrayvalueForKey:有問題。我見過一個解決方案,它使用NSCompoundPredicate在循環中添加數組項。

順便說一句,在你的多種關係鏈中,是不是你想念作者

+0

'valueForKey:'適用於'NSArray'。它構造一個新的數組,其中包含調用'valueForKey:'的結果和數組中每個元素的給定鍵(用'NSNull'替換nil值)。 –

+0

@KevinBallard請參閱我上面的內容。 – Mundi

+0

來自'[agentNames valueForKey:@「agentName」]'的任何問題都會產生完全不同的錯誤。 –