I have the following:
Deal, Contact and DealContact. A Deal can have many Contacts. A Contact can belong to many Deals. DealContact is used to maintain both of this using two relationships: to-one called deal and a to-many called contacts. I also need to store a primary contact separately in DealContact. This is another to-one relationship called primary.
Contact then has an inverse to-many to DealContact called dealcontacts and a to-one called primarydealcontact. A Deal does not have an inverse to DealContact. A deal also does not have a direct relationship to Contact.
In SQL I would've modeled this using a join table. I'm trying to carry this over using DealContact as I need additional properties stored besides just the Deal and associated Contacts.
Any suggestions on if this setup is correct or perhaps an easier setup would be very helpful.
Let me put things down with a small old school ASCII model.
Deal
- stuff
Contact
- stuff
- dealcontacts ->> DealContact
- primarydealcontact -> DealContact
DealContact
- stuff
- deal -> Deal
- contacts ->> Contact
- primary -> Contact
All right.
This stuff is not very coredataish.
First thing first.
Deal: I do not see the point not to have an inverse relationship to DealContact.deal. You'll have to handle the Deal deletions manually to ensure there is no DealContact left without a related Deal. That inverse relationship costs you almost nothing.
Contact: why is Contact.primarydealcontract a to-one relationship? You sure a Contact can't be the primary contact of several Deal?
Details all that anyway. Let's discuss what is not very coredataish. DealContact.
What's the point of that entity? Basically, you have Deal connected to many Contact, including a primary Contact. The additional fields in DealContact are most certainly related either to the Deal or a Contact, so why a dedicated entity for them?
This is how I see the entities:
Deal
- stuff // from Deal & from DealContact
- contacts ->> Contact
- primarycontact -> Contract
Contact
- stuff
- deals ->> Deal.contacts
- dealsprimary ->> Deal.primarycontact
Core Data will create the necessary relationship tables to keep track of the many-to-many relationships. Core Data does that very well.
Of course I do not know all the details of your application, so my suggestion is, well, a suggestion. Nothing more. It may suits your needs, or not. But considering what you told, it should work for you.
So it turns out that after redesigning my Core Data model and removing the DealContact entity I found that I was actually not passing along the DealContact object (which had the core data accessors) to removeContactsObject from the set. After clearing this issue (which was greatly simplified by removing DealContact entity from the model all together) [deal removeContactsObject:oneContact] worked exactly as expected.
Related
In many applications, I deal with users and finance companies (as an example) and I have long been struggling to model the relationship between the two according to Domain Driven Design principles.
In my system I can do the following:
Add a user to an existing finance company.
Add a finance company to an existing user.
I believe both are aggregate roots... Finance Company and User.
How do I model the relationship between the 2? Is it FinanceCompany.Users? or User.FinanceCompanies? Is it neither? Or am I missing knowledge of some key DDD concept(s)? The problem is if I choose one way over the other, the code is more understandable / clear from one aggregate root entry point, but not the other. Sometimes there are cases where it makes more sense to navigate to a Finance Company and add users to it, and other times there are cases where it makes more sense to navigate to a specific user and add finance companies to the user.
Is there some better way to approach this, maybe through repository methods? Is there some key concept I am not getting or understanding here? It doesn't feel right to assume the relationship between Finance Company and User belongs under either of the 2 ARs. When I store the relationship I have to store it in a table named FinanceCompanyUsers or UserFinanceCompanies, but it still doesn't seem clear.
Would I have code such as FinanceCompany.AddUser() and User.AddFinanceCompany()? or is there some completely different approach for relationships such as this?
You have already determined that both User and FinanceCompany are aggregates so each has its own life-cycle.
The problem with many domains is that we don't have a complete understanding of the relationships. As another example we can take an Order and a Product. Both are aggregates but would we have Order.AddProduct() or Product.AddOrder()? In this case it seems pretty obvious in that an Order contains a limited subset of Product entries whereas a Product may very well contain many orders and we are not really too interested in that relationship since it is a rather weak relationship. A Product can exist and be valid without any orders attached but an Order is pretty useless without at least one product entry. This means that the Order has an invariant imposed in terms of its OrderItem entries. In addition to this we have enough knowledge about this hackneyed example that we know we are going to need an associative entity (in relational theory speak) since we need additional information regarding the relationship and entering the fray would be our OrderItem table. Curiously I have not seen it called OrderProduct.
The guidance I would suggest is to pick the most appropriate side.
However, if no side is a true winner and both aggregates can exist without a relationship to the other in terms of an invariant perhaps the relationship itself is an aggregate as you have certainly alluded to. Perhaps it isn't only a UserFinanceCompany aggregate but perhaps there is a concept that is missing from the ubiquitous language that the domain experts refer to. Perhaps something like Auditor or some such that represents that relationship. This is akin to the OrderItem or OrderLine concept as opposed to OrderProduct.
Let's say you have a many to many relationship between two entities and you use MagicalRecord to manually tie them together.
IE: A Vet has many Pets and a Pet has many Pets
In the code, do you need to add the entity on both sides of the relationship;
ie:
[vet1 addPetObject:cust1Pet1];
[vet1 addPetObject:cust1Pet2];
[vet1 addPetObject:cust1Pet3];
[cust1Pet1 addVetObject:vet1];
[cust1Pet2 addVetObject:vet1];
So, do I need to add the pet object to the vet, and then add the vet to the relevant pet object -- or will Core data / Magical record handle this relationship and tie them on both sides by itself?
Many thanks.
If the relationships are defined as inverse relationships of each other in the Core Data
model inspector then you need only set one of them. Core Data will automatically update
the inverse relationship. (This is in fact unrelated to MagicalRecord.)
I´m a little confused about inheritance and relationships in core data, and I was hopping someone could drive to the right path. In my app i have created 3 entities, and none of them have (and are not suppose to have) common properties, but there´s gonna be a save and a load button for all the work that the user does. From my understanding I need to "wrap" all the entities "work" into an object which will be used to save and load, and my question is, do I need to create relationships between the entities? Because I have to relate them somehow and this is what make sense to me. Is my logic correct?
I'm implementing a budget calculator, and for the purpose of everyone understand what my issue is, I´m going to give an practical example and please correct me if my logic is incorrect:
Let´s just say you are a fruit seller, and because of that it´s normal to have a database of clients and also a fruit database with the kinds of fruit you sell. From my understanding I find two entities here:
Client with properties named: name, address, phone, email, etc.
Stock with properties named: name, weight, stock, cost, supplier, etc.
TheBudget with properties named: name, amount, type, cost, delivery, etc.
I didn´t put all the properties because I think you get the point. I mean as you can see, there´s only two properties I could inherit; the rest is different. So, if I was doing a budget for a client, I can have as many clients I want and also the amount of stock, but what about the actual budget?
I´m sorry if my explanation was not very clear, but if it was..what kind of relationships should I be creating? I think Client and TheBudget have a connection. What do you advise me?
That's not entirely correct, but some parts are on the right track. I've broken your question down into three parts: relationships, inheritance and the Managed Object Context to hopefully help you understand each part separately:
Relationships
Relationships are usually used to indicate that one entity can 'belong' to another (i.e. an employee can belong to a company). You can setup multiple one-to-many relationships (i.e. an employee belongs to a company and a boss) and you can setup the inverse relationships (which is better described with the word 'owns' or 'has', such as 'one company has many employees).
There are many even more complicated relationships depending on your needs and a whole set of delete rules that you can tell the system to follow when an entity in a relationship is deleted. When first starting out I found it easiest to stick with one-to-one and one-to-many relationships like I've described above.
Inheritance
Inheritance is best described as a sort of base template that is used for other, more specific entities. You are correct in stating that you could use inheritance as a sort of protocol to define some basic attributes that are common across a number of entities. A good example of this would be having a base class 'Employee' with attributes 'name', 'address' and 'start date'. You could then create other entities that inherit from this Employee entity, such as 'Marketing Rep', 'HR', 'Sales Rep', etc. which all have the common attributes 'name', 'address' and 'start date' without creating those attributes on each individual entity. Then, if you wanted to update your model and add, delete or modify a common attribute, you could do so on the parent entity and all of its children will inherit those changes automatically.
Managed Object Context (i.e. saving)
Now, onto the other part of your question/statement: wrapping all of your entities into an object which will be used to save and load. You do not need to create this object, core data uses the NSManagedObjectContext (MOC for short) specifically for this purpose. The MOC is tasked with keeping track of objects you create, delete and modify. In order to save your changes, you simply call the save: method on your MOC.
If you post your entities and what they do, I might be able to help make suggestions on ways to set it up in core data. You want to do your best to setup as robust a core data model as you can during the initial development process. The OS needs to be able to 'upgrade' the backing store to incorporate any changes you've made between your core data model revisions. If you do a poor job of setting up your core data model initially and release your code that way, it can be very difficult to try and make a complicated model update when the app is in the wild (as you've probably guessed, this is advice born out of painful experience :)
Core data is not a database and so I am getting confused as to how to create, manage or even implement Lookup tables in core data.
Here is a specific example that relates to my project.
Staff (1) -> (Many) Talents (1)
The talents table consists of:
TalentSkillName (String)
TalentSkillLevel (int)
But I do not want to keep entering the TalentSkillName, so I want to put this information into another, separate table/entity.
But as Core Data is not really a database, I'm getting confused as to what the relationships should look like, or even if Lookup tables should even be stored in core data.
One solution I'm thinking of is to use a PLIST of all the TalentSkillNames and then in the Talents entity simply have a numeric value which points to the PLIST version.
Thanks.
I've added a diagram which I believe is what you're meant to do, but I am unsure if this is correct.
I'd suggest that you have a third entity, Skill. This can have a one to many relationship with Talent, which then just has the level as an attribute.
Effectively, this means you are modelling a many-to-many relationship between Staff and Talent through the Skill entity. Logically, that seems to fit with the situation you're describing.
I'm still wrapping my head around DDD, and one of the stumbling blocks I've encountered is in how to handle associations between separate aggregates. Say I've got one aggregate encapsulating Customers and another encapsulating Shipments.
For business reasons Shipments are their own aggregates, and yet they need to be explicitly tied to Customers. Should my Customer domain entity have a list of Shipments? If so, how do I populate this list at the repository level - given I'll have a CustomerRepository and a ShipmentRepository (one repo per aggregate)?
I'm saying 'association' rather than 'relationship' because I want to stress that this is a domain decision, not an infrastructure one - I'm designing the system from the model first.
Edit: I know I don't need to model tables directly to objects - that's the reason I'm designing the model first. At this point I don't care about the database at all - just the associations between these two aggregates.
There's no reason your ShipmentRepository can't aggregate customer data into your shipment models. Repositories do not have to have a 1-to-1 mapping with tables.
I have several repositories which combine multiple tables into a single domain model.
I think there's two levels of answering this question. At one level, the question is how do I populate the relationship between customer and shipment. I really like the "fill" semantics where your shipment repository can have a fillOrders( List customers, ....).
The other level is "how do I handle the denormalized domain models that are a part of DDD". And "Customer" is probably the best example of them all, because it simply shows up in such a lot of different contexts; almost all your processes have customer in them and the context of the customer is usually extremely varied. At max half the time you are interested in the "orders". If my understanding of the domain was perfect when starting, I'd never make a customer domain concept. But it's not, so I always end up making the Customer object. I still remember the project where I after 3 years felt that I was able to make the proper "Customer" domain model. I would be looking for the alternate and more detailed concepts that also represent the customer; PotentialCustomer, OrderingCustomer, CustomerWithOrders and probably a few others; sorry the names aren't better. I'll need some more time for that ;)
Shipment has relation many-to-one relationship with Customer.
If your are looking for the shipments of a client, add a query to your shipment repository that takes a client parameter.
In general, I don't create one-to-mane associations between entities when the many side is not limited.