Reputation: 255
I am trying to understand the concept in saving and retrieving records in a one-to-many relationship entities in CoreData. i have two tables Products (Master) and Sales (Details) hence (one-to-many) relationship with the relationship key being (sales).
Issue 1: when registering a sale to a product. i create an instance of the Sales entity, populate the values, then add it to the product.sales (relationship) and attempt a managedObjectContext save.
First Question: Do i also have to enter the instance of the Sales entity into the Sales Entity? or that will be updated automatically since there is a relationship?
Second Question: If i want to query all the sales that happened to date, do i query the Sales Entity? or do i query the relationship in the Products Entity?
Thanks for your help!
Upvotes: 0
Views: 4369
Reputation: 1183
As of swift 3 you don't have to create the properties of a class of an entity that you created in Core Data because Core Data does that for you. You do have to initialize those properties though. Same thing is true for relationships. For example in the case of the product Class (the parent) the relationship to sales(the child) is already instantiated for you. So you can access and set the Entity Sale by getting the instance of the relationship in the Product Class. There might be other ways of doing that but I think using extensions is pretty cool.
extension Product {
//You would call this constructor like that: Product(sale) from any //part of your program as long as you "import CoreData" //If its 1 Sale then s 1-1 if it's more than 1 it's 1-many convenience init?(Sale or Sales) {
let MOC = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
self.init(context: MOC)
//case 1 when sale is 1-many
let sale = Sale(context: MOC)
//case 2 when sale is many-many(this can be an array of objects that you sent)
let sale1 = Sale(context: MOC)
let sale2 = Sale(context: MOC)
let sale3 = Sale(context: MOC)
//setting sale object
sale.property = ""
//Now is time to set the relationship with the object that you just set
//case when is 1 - many
self.sale = sale
//case when is many - many
self.sale?.adding(sale1)
self.sale?.adding(sale2)
self.sale?.adding(sale3)
}
Now your Product will be related to your sales....
Upvotes: 0
Reputation: 63
let manageObjectContext = appDelegateObj.managedObjectContext
let entity = NSEntityDescription.entityForName("", inManagedObjectContext:manageObjectContext)
let manageObj = NSManagedObject(entity: entity!,insertIntoManagedObjectContext: manageObjectContext)
manageObj.setValue("Mark Developer", forKey: "AttributeName")
do {
try manageObjectContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
Upvotes: 1
Reputation: 12820
First Question: Do i also have to enter the instance of the Sales entity into the Sales Entity? or that will be updated automatically since there is a relationship?
Something you might not realize here is that you are inherently saving the object by adding it to the managedObjectContext
. As soon as you do something like
let sale = Sale(context: managedObjectContext)
followed by
managedObjectContext.save()
the context issues a save request to your persistent store (your actual SQL database).
Therefore your question whether you need to store the Sale as well is answered, it will always be stored upon saving the context.
Second Question: If i want to query all the sales that happened to date, do i query the Sales Entity? or do i query the relationship in the Products Entity?
That depends...
First let me give you a little tip/best practise:
Always make sure to set up an inverse relationship
In the Core Data Editor for your Product
entity's relationships you can do something like this:
Your sales relationships look something like this:
A relationship is nothing more but a dependency between two entities, therefore there is always an inverse relationship between two entities, make sure you hook them up as shown above.
Why am I telling you this ? Remember I mentioned it depends what entity you do your query on ? This is where it matters.
For example, if you want the Sale
for a given Product
, you would query the product itself (by querying its relationship called sale
):
let product = [A product instance from your Core Data store]
let sale = product.sale // returns the sale the product is associated to
If you want all the products from a given sale, you would query the Sale
entity leveraging the products
relationship:
let sale = [A sale from your Core Data store]
let products = sale.products // the products contained in the sale
You mentioned that you want all the sales to a given date:
It would not make any sense querying the Product
entity for that because each product only has a relationship to the sale it is contained in.
So, to answer your question, you should query the Sale
entity to retrieve all the sales to a given date.
I hope that helps, let me know if something is unclear.
Upvotes: 1
Reputation: 122
I will need to look into this a bit further, as I too am still getting my head around Core Data, but until I can find the time to do that I think what might work for you is this:
issue 1: to also enter the sale into the sales entity. I do not believe this will be done for you. Where relationships really become important is in deleting. You can specify what you want he delete rules to be, whether nullify, deny, cascade, or no action. Raywenderlich.com has an excellent tutorial series on Core Data that may help you.
issue 2: I think it depends on in which table (although in CoreData the term is ManagedObject) the data you are looking for is stored. It would make most sense to me to query the sales entity. You don't have to query the whole sales entity if you do not want to. You can specify search parameters.
Upvotes: 0