Reputation: 115
I'm trying to verify I understand Core Data relationships and/or possibly how to handle duplicates.
In my example below, I have entity Account in a to-many relationship with entity Transaction Date. I'm thinking to-many as there will be multiple dates under the one Account.
Where I'm getting confused is that I only want to have one specific date... meaning, only one date and no duplicates. The intent is then to have entity Transaction Date to have a to-many relation with entity Event. So account XYZ will have trans date of 06/11/2012 and multiple entries for entity Event. Then account XYZ will have trans date of 06/12/2012 and multiple entries for entity Event.
Is the relationship between Account and Trans Date truly a to-many or to-one? If it is a to-many... how are duplicates handled? How do I keep only one date in entity Trans Date? If my code is adding by entries into Event and Trans Date, is some handling done there? How?
I'm guessing Account to Trans Date should be to-one... but really not sure at this point.
/-----------------------\ /----------------------\ /------------------\
| Account | | Transaction Date | | Event |
|-----------------------| |----------------------| |------------------|
| name | | addDate | | amount |
| balance | | | | |
|-----------------------| |----------------------| |------------------|
| heldByAcct | <-\ | | | |
| | \->> | inAcct | | |
| | | heldByEvent |<-\ | |
\-----------------------/ \----------------------/ \->>| inTrans |
\------------------/
Upvotes: 1
Views: 489
Reputation: 17218
To model a transaction register, I'd suggest making addDate a property of Event and removing Transaction Date entirely.
It significantly simplifies the work you need to do to manage the object graph, and removes the need to de-duplicate the dates.
If you need to produce a list of unique dates, you can do it on the fly with distinctUnionOfSets as described in the answer to this question: CoreData get distinct values of Attribute.
Upvotes: 0
Reputation: 33428
I'm not sure I understood what you are trying to achieve but I'll try to give you some suggestions.
First
If an Account
can have only one Transaction Date
, I think you should set a one-to-one relationship. In this manner you are sure that one Account
has a Transaction Date
and viceversa. Behind, Core Data will set up your db so that your Account
table will have a field for the ID of the corresponding Transaction Date
object.
Second
If you are setting up a checkout mechanism and the Account
can have multiple transaction (e.g. only one per day) you need to set up a one-to-many relationship. If you need to check for a single transaction per day, you need to perform the check manually. Set a request against Transaction Date
with a predicate for a specific Account
and date and see if the count is greater than one. If no, add that Transaction Date
.
NSInteger count = [fetchRequest countForFetchRequest:&error]; // query against `Transaction Date`
if(count >= 1) // not allowed
else // allowed
Usually when I need to check for duplicates, I use a guid as an attribute for an entity (e.g. guid of type NSString
). So, in your Transaction Date
you could use such a mechanism. Then you could set the fetch request with a predicate like the following:
[NSPredicate predicateWithFormat:@"guid == %@ AND inAcct == %@", @"12345", [self currentAccount]];
Each time you insert a new Transaction Date
you could generate a new guid based on the date (without time) and the specific Account
(use your own protocol to do this).
Thinking on it, you could also save and check the date without its time part (category-on-nsdate). I think it will work but you need to try. By means of this you could simply use a predicate without a guid. For example:
[NSPredicate predicateWithFormat:@"addDate == %@ AND inAcct == %@", [self currentDate], [self currentAccount]];
Hope it helps.
Upvotes: 1