LONGI
LONGI

Reputation: 11453

Objective C Core Data: Fetch over several Entities

Just starting with CoreData and just wondering, how to create "complex" FetchRequest. I have following data-structure (minified for question):

enter image description here

There are several books and several people (creators). Creators can be an author, translator, illustrator (...). Some "Creator" have several "roles", that`s why I ended up with the "CreatorBook-Entity", because sometimes the same creator has different roles for different books..

Anyway... In the app I show the Book and there's a CollectionView with other Books from the same Author (=Creator with the role= Author). I tried to create a FetchRequest but didn`t know how to combine the different Entities, so at the moment I iterate through CoreData like the following:

//Get all Creators from Book and get the first Author
Creator* author;
NSSet* creatorSet = self.book.creator;  
if( [creatorSet count] > 0 ){
    for(CreatorBook *uObjects in creatorSet){
        if([uObjects.role isEqualToString:@"Author"]){
            author = uObjects.creator;
            break;    //get first author 
        }
    }
}

//Get all the Book from the same Author
if(author != nil){

    NSSet* authorBooks = author.book;

    NSMutableArray* books = [[NSMutableArray alloc] init];
    for(CreatorBook* object in authorBooks){
        Book* a = object.book;

        [books addObject:a];

    }
    _authorBookCollection = books;

    [self.bookPreview reloadData];
}

Is there a way to get the same result with one FetchRequest?

How can I get all Books if there are more than one Author? (my code above stops at the first)

Is it possible to fetch all Books ordered by an attribute from Creator (for example the authors fullname (more than one author -> show book several times))?

Upvotes: 0

Views: 131

Answers (1)

Mundi
Mundi

Reputation: 80273

First, your attribute name creator for the Book entity is misleading. Potentially, a book has more than one creator, i.e. an author, illustrator, etc. So I used creators (in the plural) to reflect the to-many relationship. Similarly, I renamed the to-many relationship from Creator to the join table books.

Second, I am assuming that the book has only one author - or one creator with the same role. Of course, it is thinkable that this could be different (there is a solution for that case as well).

NSSet *creatorsOfThisBook = book.creators;
Creator *authorOfThisBook = [[creatorsOfThisBook filteredSetUsingPredicate:
   [NSPredicate predicateWithFormat:@"role = %", @"author"]] anyObject];
NSSet *booksByThisAuthor = [[authorOfThisBook.books filteredSetUsingPredicate:
   [NSPredicate predicateWithFormat:@"role = %", @"author"]]
   valueForKeyPath:@"book"];

You can see that if a Creator is only an author, you could leave out the second predicate.

Upvotes: 0

Related Questions