I'm trying to set up a simple Core Data model like the following:
Order(code, customer)
Book(code, title, price)
OrderBook(order_code, book_code, quantity)
From Core Data documentation I see that it's not possible to model a many-to-many relationship adding to it attributes. For this reason I modeled it like the following.
where:
Order
to OrderBook
there is a one-to-many relationship with a delete rule Cascade
OrderBook
to Order
there is a one-to-one relationship with a delete rule No Action
The same is valid for Book
and OrderBook
.
First question: Is this model valid?
Supposing that the model is ok, I created the corresponding NSManagedObject
subclasses.
Book.h/.m
Order.h/.m
OrderBook.h/.m
That said, I have the necessity to populate the corresponding db by means of Core Data mechanism. To do this I created the corresponding categories like the following, where each category is responsible to create itself (to maintain object encapsulation).
Book+Creation.h/.m
Order+Creation.h/.m
OrderBook+Creation.h/.m
For example Book+Creation
category has a class method like the following:
+ (Book *)bookWithXMLElement:(GDataXMLElement *)xmlElement inManagedObjectContext:(NSManagedObjectContext *)context;
Now I have a problem and I don't know how to resolve it.
The model population has to happen at different times. The table for books is populated first (I'm creating a catalog of books from an xml file). Once finished, I'm able to populate order and orderbook tables. To populate these tables I'm using an xml file like the following:
<orders>
<order>
<code>1234</code>
<book>2567</book>
<customer>299</customer>
<quantity>4</quantity>
</order>
</orders>
To create an Order
managed object I've created the following method in its category Order+Creation
:
+ (Order *)orderWithXMLElement:(GDataXMLElement *)xmlElement inManagedObjectContext:(NSManagedObjectContext *)context;
Once created, the object is passed to OrderBook+Creation
class method category to create an OrderBook
managed object:
+ (OrderBook *)orderWithXMLElement:(GDataXMLElement *)xmlElement withOrder:(Order*)order inManagedObjectContext:(NSManagedObjectContext *)context
{
OrderBook* orderBook = [NSEntityDescription insertNewObjectForEntityForName:@"OrderBook" inManagedObjectContext:context];
orderBook.order = order;
//orderBook.book = <-- how can I retrieve the book?
return orderBook;
}
What is missing is how to create (or retrieve) the Book
object to assign it to OrderBook
object.
Second question: How can I retrieve a Book
object and assign it to OrderBook
? Do I have to create a NSFetchRequest
to fetch the right object Book
(the one that has the same code in xml file, e.g. <book>2567</book>
)? If so, is there a mechanism to improve performance for the fetching rquest?
Remember that book table is already populated.
Hope it is clear. Thank you in advance.
If you have performance problems with the fetch request (hard to say without knowing the numbers involved) you could fetch the whole set of books into memory (again, might not be practical depending on the numbers) and then use array filtering/enumeration to find the specific item, but you should definitely build and profile the simplest option first.
The delete rule types are described here, nullify is correct for the to-one relationship from orderBook to Book and Order:
Nullify
Set the inverse relationship for objects at the destination to null.
For example, if you delete a department, set the department for all the current members to null. This only makes sense if the department relationship for an employee is optional, or if you ensure that you set a new department for each of the employees before the next save operation.
This means if you delete an orderBook, then it is removed from the orderBooks and bookOrders sets in the Order and Book entities.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With