2009-06-02 13 views
32

Tôi đang tìm nạp một tập hợp các đối tượng từ kho lưu trữ Dữ liệu cốt lõi bằng cách sử dụng một yêu cầu tìm nạp và một biến vị ngữ. Vị từ hiện tại của tôi chỉ đơn giản là kiểm tra xem một thuộc tính là> = một giá trị nhất định. Điều này tất cả các công trình lớn, ngoại trừ việc tôi muốn cuối cùng loại trừ bất kỳ đối tượng hiện đang được tổ chức trong một mảng. Về cơ bản, tôi cần có thể loại trừ một tập hợp các đối tượng và cách duy nhất tôi nghĩ mình có thể thực hiện việc này là có thể lấy danh sách objectID từ mảng đối tượng được quản lý của mình và tạo một biểu thức khác trong vị từ của tôi để đảm bảo rằng bất kỳ đối tượng nào được trả lại không có cùng một số objectID. I E. @"ANY records.objectID NOT IN %@", arrayOfObjectID.Dữ liệu cốt lõi: Truy vấn đối tượngID trong một vị từ?

Tôi làm cách nào để thực hiện việc này?

Trả lời

64

Một vị như

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (self IN %@)", arrayOfExcludedObjects]; 

nơi đơn vị được yêu cầu lấy là thực thể của các đối tượng trong mảng, nên làm những gì bạn muốn. Tất nhiên, điều này có thể được kết hợp với các mệnh đề khác trong một vị từ đơn lẻ cho một yêu cầu tìm nạp.

Nói chung, so sánh đối tượng (ví dụ: self == %@ hoặc self IN %@) so sánh trên objectID trong Truy vấn dữ liệu cốt lõi. Đối số có thể là một cá thể NSManagedObject hoặc một thể hiện NSMangedObjectID. Vì vậy, định dạng vị từ ở trên có thể mất arrayOfExcludedObjects hoặc [arrayOfExcludedObjects valueForKey:@"objectID"] làm đối số.

+1

Tha nks cho sự giúp đỡ của bạn. Tôi đã thử sử dụng [vị ngữ NSPredicateWithFormat: @ "tự KHÔNG IN% @", myArrayOfManagedObjects] nhưng tôi vẫn nhận được một 'Không thể phân tích chuỗi định dạng "tự KHÔNG IN% @" lỗi khi chạy. Ý tưởng nào? –

+0

Xin lỗi .. lỗi của tôi không được kiểm tra trước khi tôi đăng. Tôi đã sửa câu trả lời của mình (sử dụng "NOT (self IN% @)" thay vì "self NOT IN% @"). –

+0

Điều này làm việc tốt cho tôi. Tôi đã sử dụng nó để lọc xuống bằng cách sử dụng logic phức tạp không được hỗ trợ trong SQL. Nhưng predicateWithBlock không hoạt động (vì lý do hợp lý) trên SQL. –

9

Trong khi câu trả lời của @ BarryWark là chính xác khi làm việc với các yêu cầu tìm nạp, tôi muốn viết cảnh báo cho những người sẽ cố gắng áp dụng quy tắc này để lọc dữ liệu cốt lõi cho nhiều mối quan hệ.

Ngay: Nếu khi lọc to-nhiều mối quan hệ bạn sử dụng một ngữ và mảng của các đối tượng cho TRÊN truy vấn là một mảng của objectIDs - sau đó bạn nên sử dụng self.objectID trong chuỗi truy vấn của bạn như

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", arrayOfObjectIDs]; 

Bởi vì chỉ sử dụng (self IN %@) trong trường hợp lọc nhiều mối quan hệ sẽ dẫn đến kết quả không chính xác - nó chỉ là một NSArray đánh giá các biến vị ngữ và không biết gì về công cụ NSManagedObjectID của dữ liệu lõi.

Tôi đã tạo mã kiểm tra đặc biệt cho thấy điều này. Xin lỗi cho rất nhiều dòng, nhưng họ có giá trị nó. Có hai thực thể: Người dùng và Bài đăng và Người dùng có mối quan hệ to-nhiều có tên là "bài đăng".

User *user = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([User class]) inManagedObjectContext:managedObjectContext()]; 

Post *post = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Post class]) inManagedObjectContext:managedObjectContext()]; 

[user addPostsObject:post]; 

[managedObjectContext() save:nil]; 

// 1. Both filtered relationship array and fetch result are correct! 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self IN %@)", @[ post ]]; 

NSSet *filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
NSArray *fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 2. Filtered relationship array is empty (wrong), fetch result is correct, ! 
predicate = [NSPredicate predicateWithFormat:@"(self IN %@)", @[ post.objectID ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 3. Filtered relationship array is empty (wrong), fetch result is correct 
predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", @[ post ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 4. Filtered relationship array is correct, fetch result is correct 
predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", @[ post.objectID ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

đầu ra TLDR giải pháp

<redacted> Predicate: SELF IN {<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>"; })} 

<redacted> filteredRelationship: {(<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>"; }))} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: SELF IN {0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1>} 

<redacted> filteredRelationship: {()} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: objectID IN {<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>";})} 

<redacted> filteredRelationship: {()} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: objectID IN {0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1>} 

<redacted> filteredRelationship: {(<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>";}))} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 
0

Swift 3

tôi phải đối mặt với tình trạng tương tự do đó tôi đang đăng một giải pháp nhanh chóng 3 dưới đây

let predicate = NSPredicate(format:"NOT (self IN %@)",[arrayofNSManagedObjects])