Breezejs: create entities from junction table in many to many relationship - breeze

I have a many to many relationship between 2 tables (Entity1 and Entity2), with a junction table (JunctionEntity).
In Breeze client, I want to:
Create an object of type Entity1, e1
Link e1 to one or more objects of type Entity2 that already exist. To do that, I create instances of JunctionEntity, j1 and j2.
Savechanges
To do that, I create e1 using manager.createEntity, and use also manager.createEntity to create j1 and j2. I just set, in these objects, the properties: Entity1Id and Entity2Id.
Problem: I see in the console that these entities are passed from the browser to the server. But when debugging on the server, e1's JunctionEntity list is null.
Should you need more information about this problem, please let me know.
I feel I must be doing a conceptual mistake.
Thanks for your help
Nicolas

Ok, I was too impatient, as often...
I was encountering this problem that my junctionentity list was null, which is actually normal!
All I had to do was let the code run a little longer, to see that the entities from the function table get correctly saved afterwards. They are sent from the client to the server, but as separate entities, which makes perfect sense.
Patience is the mother of all virtues, when will I ever learn that one? :)

Related

Core Data Relationship For Unidirectional One to Many

What is the best practice for creating Unidirectional One to Many Relationships in Core Data?
For example...
Lets take two classic entity examples, "teacher" and "student".
Each student has one teacher, and each teacher has many students.
In CoreData right now you are forced to provide an inverse such that teacher is forced to have a reference to a 'student'. If you don't you get this nice warning that says something along the lines of...
file:///Users/josephastrahan/Documents/VisualStudioProjects/Swift3WorkOrders/WorkOrders/WorkOrders/WorkOrders.xcdatamodeld/WorkOrders.xcdatamodel/: warning: Misconfigured Property: Teacher.student should have an inverse
What if I don't want teacher to have a reference to student?
Some other posts have brought up that I should just allow the inverse anyways but I think this inverse may be causing an issue with one of my projects.
That said let me explain my exact issue.
Lets say that our teacher has a unique attribute int64 called 'id'. Lets say the students also have unique attribute int64 called 'id'.
The int64 is enforced to be unique by adding a constraint on the model for teacher on id. (refer to image below to see how that is done)
Every year there is new students but the teachers stay the same. So I decided that I want to delete all the students without deleting the reference to the teacher. So I set the delete rule to 'nullify' for the relationship for the teacher to student and 'nullify' for the student to teacher.
Now when I create a new student I want to assign one of the existing teachers to that student... (something like student.teacher = teacher object with id of 1 or the same id as before) however!! , because the teacher has the inverse relationship to a student that no longer exists (which in theory should be null) the program crashes!
I know this is the case as I've used print console logs to narrow it down the exact point that it occurs. Also I know this because if I add the delete rule of cascade for student the crash will go away but...then I lose my teacher! which I don't want...
Some things that I think might be the issue:
1.) When I do my testing I do it at the startup of the program which creates a new context everytime. Could it be that because I never deleted teacher it still thinks it refers to a student from a context that no longer exists? (if I'm even saying this right...)
I'm not sure the best solution to acheive what I'm trying to do with Coredata and any advice is much appreciated!
Note:
Forgot to mention I also have the Merge Policy of: NSMergeByPropertyObjectTrumpMergePolicy, which will overwrite the old data with the new. When I'm creating new students I'm creating new teachers also just using the same id which should follow this policy.
You are almost there.
The advice to keep the inverse relationship is a good one. Keep it.
Your issue is likely caused by different contexts. Instead of holding on to a teacher object in memory, you should fetch the teacher (based on the id) in the context in which you intend to use it.
Your nullified students should not have any impact. A to-many relationship is really a Set<Student>. Make sure the set is empty.
NB:
If you want to keep the student in the database (for historical purposes) - it seems from your description that this is the case - you might also consider another scheme: give your students another attribute (such as a year) and use that to filter the student list. You would not have to delete or nullify anything. You could also do some more interesting time-based queries on the data.
Unique Constraints are available with iOS9. Which have helped iOS Developers with adding and updating records in CoreData.
Unique Constraints make sure that records in an Entity are unique by the given fields. But unique constraints along with To-Many relationship leads to a lot of weird issues while resolving conflicts.
e.g. “Dangling reference to an invalid object.”
This post is basically focused to a small problem that may take days to fix.
http://muhammadzahidimran.com/2016/12/08/coredata-unique-constraints-and-to-many-relationship/

How do entities in relationship know what to join on

This is a basic question from someone transitioning from SQL-based databases that I normally sweep under the carpet but would really like to understand. When two entities are joined in a relationship, how does Core Data figure out what attribute to join on? Does it figure it out by matching attribute names, or just how does it know?
I'm asking to understand why following code is not working.
I have one entity, Books with attributes as follows:
aid|authorname
I have another entity, Authors with attributes
bid|bookname|authorid
//note authorid here is spelled differently than in the author entity.
Authors has a Many relationship to Books named book
Books has One relationship to Authors named author.
In the books VC, in the .h file I have
#property (nonatomic,weak) Books * book;
In the .m file I have following code in ViewDidLoad
NSString *authorname = self.book.author.authorname;
//this is supposed to be book-object.author-relationship,authorname-attribute
//however it displays blank
NSLog(#"author name%#",authorname); //displays blank
I have very similar code working elsewhere in the app that works fine (though both relationships are one-to-one) so I think I must be missing something dumb somewhere.
However, it has prompted me to wonder exactly how does core-data figure out which author goes with which books?
Are the attribute names supposed to match up?
Thanks for any insights.
CoreData "knows" that two objects are related if and only if you tell it, which you do by (assuming you have defined the relationship in the data model editor) assigning one object to the relationship property of the other object:
myBook.author = myAuthor;
or equivalently
[myAuthor addBooksObject:myBook];
Once you've done that, CoreData will "know" that those two objects are related (even if you save the data then reload it). This is completely independent of the attributes (such as aid and authorid) that you might think indicate that two objects are related.
If you want Books to be related to the Author with aid equal to the Book's authorid, you have program it that way. So, if for example you sync an Author from your server, with aid = 123, and then sync some Books with authorid = 123, you will need to fetch (unless you already have a reference to it) the Author with aid = 123, and set the relationship with code similar to the above. I suspect it is this step which you have missed, and is causing the blank author name.
If you do this during your sync process, you can thereafter just rely on the relationship, with no need to worry about primary keys, foreign keys, joins, etc. Behind the scenes, CoreData maintains a unique primary key for each entity, and foreign keys for each relationship. You can see these if you directly inspect the underlying SQLite database, and/or if you activate SQLDebug.

Preventing duplicate NSManagedObjects

Consider two entities Author and Book that are in a many-to-many relationship that are imported into my CoreData store from an external database. What I am confused about is, should I create a new NSManagedObject for each author, even if this author is already in the store? How do I even know that two authors with the same name are the same person? I could for instance end up with 10 John Smiths, and 5 of them are the same person, but there is no way to check this when importing the data, right? Suppose I want to do a fetchrequest for one of these John Smiths, I will still get 10 results. He may also appear as J. Smith, or J.A. Smith. But J. Smith could also be Jenny Smith.
Should I just create an NSManagedObject for each author, and not worry about possible duplicates, or are there other ways around this?
How do I even know that two authors with the same name are the same person?
You don't, and that's the core of your problem right there. You need to allow duplicate names, because names are (usually) not unique. Any technical solution to avoiding or removing duplicates based on name is virtually guaranteed to corrupt your data.
It's not clear where your data is coming from, so it's hard to say what the best fix is. If this is user-entered data, let the user edit an existing author to add or remove titles, to prevent a duplicate. Offer the option to merge two entries in case the user accidentally creates a duplicate.
If the data comes from an online service of some kind, you pretty much have to take what they give you. If they have duplicate entries for authors, you can't reliably do anything about it. You could easily find duplicate names, but that doesn't mean they're the same person.
use a fetch or create pattern as explained in the apple CoreData docs
Core Data doesnt have an implicit uniquing algorithm.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html
(they call it find or create) ;)
In order to disambiguate people (or authors) you would need either a "unique" attribute, say an author_id which is guaranteed to be unique when an author will be created.
The other approach is to use heuristics to determine if an object has possibly duplicates This second approach sounds more complex, and actually it IS more complex ;)
Unfortunately, Core Data does not support "unique attributes" (unique keys).
Both approaches can be implemented as proper managed object "validations", which get invoked when the context will be saved.
A sophisticated solution would use a separate index maintained per unique attribute and per context. Using Core Data queries as shown in the sample snippets "Implementing Find-or-Create Efficiently" in order to confirm that the "unique constraint" is fulfilled each time the context is saved, will become quite slow for large data sets.
With iOS 9, Apple introduced unique constraints to Core Data. Now you can specify an attribute that has to be unique.

Core Data Model

I'm struggling with creating a suitable Core Data model for my app. I'm hoping someone here can provide some guidance.
I have two entities -- "Goals" and "Items". The Goals entity contains only a goal description, but any goal may have any number of subgoals, and these may extend multiple levels in a tree structure. Subgoals are to be contained within the same entity, so presumably the Goal entity will contain a pointer to "parent" which will be the parent goal of any subgoal.
There will also be an "Items" entity that contains a couple of text fields and a couple of binary items, and must be linked (ideally, by a unique identifier, perhaps objectID) to the particular goal or subgoal the item(s) are related to.
I am totally fumbling with how to set this model up. I know what attributes need to be in each entity, but the relationships, particularly between goals and "subgoals", has me stumped. I don't seem to be able to turn up any good examples of tree structures in Core Data on the Internet, and even the couple of books I have on Core Data don't seem to address it.
Can anyone here help an old SQL programmer get headed the right direction with these relationships in Core Data? Thanks.
Have you tried creating a one-to-many from Goal to itself, and a one-to-one from Goal to Item? The only thing I would worry about here is circular references.
Also, read Relationships and Fetched Properties in the CoreData Programming Guide.
Here is how it is done:
You set up a to-many relationship from Goal to Item in the model editor. Don't use any ids, foreign keys etc. This is old-fashioned database thinking - you can forget about it. Here we are only dealing with an object graph. The database layer is just an implementation detail for persisting the data.
Make two more relationships in entity Goal to itself: a to-one called parent, a to-many called subGoals. Make them the inverse of each other. Simple!
QED is correct, you can create a to many relationship on goal (call it subgoals) as well as a to-one relationship on goal (call it parentGoal) and set them as inverses to each other.
Then create another to many relationship (call it items) on the goal entity, with the inverse being a to one relationship on the item entity (call it goal). Then you're all set. You don't need to link items with a unique id, just add them to the items relationship.
Also note that if you did want to give items a unique id, do not use the objectID. The objectID should only be used as a temporary id as they are not guaranteed to remain the same. In fact they will change if you ever do a Core Data migration.
One way, though not really great, is to create a another entity, say subGoal, and each goal has one subGoal and each object of subGoal has many goal.

SQL Relationships

I'm using MS SQL Server 2008R2, but I believe this is database agnostic.
I'm redesigning some of my sql structure, and I'm looking for the best way to set up 1 to many relationships.
I have 3 tables, Companies, Suppliers and Utilities, any of these can have a 1 to many relationship with another table called VanInfo.
A van info record can either belong to a company, supplier or utility.
I originally had a company_id in the VanInfo table that pointed to the company table, but then when I added suppliers, they needed vaninfo records as well, so I added another column in VanInfo for supplier_id, and set a constraint that either supplier_id or company_id was set and the other was null.
Now I've added Utilities, and now they need access to the VanInfo table, and I'm realizing that this is not the optimum structure.
What would be the proper way of setting up these relationships? Or should I just continue adding foreign keys to the VanInfo table? or set up some sort of cross reference table.
The application isn't technically live yet, but I want to make sure that this is set up using the best possible practices.
UPDATE:
Thank you for all the quick responses.
I've read all the suggestions, checked out all the links. My main criteria is something that would be easy to modify and maintain as clients requirements always tend to change without a lot of notice. After studying, research and planning, I'm thinking it is best to go with a cross reference table of sorts named Organizations, and 1 to 1 relationships between Companies/Utilities/Suppliers and the Organizations table, allowing a clean relationship to the Vaninfo table. This is going to be easy to maintain and still properly model my business objects.
With your example I would always go for 'some sort of cross reference table' - adding columns to the VanInfo table smells.
Ultimately you'll have more joins in your SP's but I think the overhead is worth it.
When you design a database you should not think about where the primary/foreign key goes because those are concepts that doesn’t belong to the design stage. I know it sound weird but you should not think about tables as well ! (you could implement your E/R model using XML/Files/Whatever
Sticking to E/R relationship design you should just indentify your entity (in your case Company/supplier/utilities/vanInfo) and then think about what kind of relationship there is between them(if there are any). For example you said the company can have one or more VanInfo but the Van Info can belong only to one Company. We are talking about a one – to- many relationship as you have already guessed. At this point when you “convert” you design model (a one-to many relationship) to a Database table you will know where to put the keys/ foreign keys. In the case of a one-to-Many relationship the foreign key should go to the “Many” side. In this case the van info will have a foreign keys to company (so the vaninfo table will contain the company id) . You have to follow this way for all the others tables
Have a look at the link below:
https://homepages.westminster.org.uk/it_new/BTEC%20Development/Advanced/Advanced%20Data%20Handling/ERdiagrams/build.htm
Consider making Com, Sup and Util PKs a GUID, this should be enough to solve the problem. However this sutiation may be a good indicator of poor database design, but to propose a different solution one should know more broad database context, i.e. that you are trying to achive. To me this seems like a VanInfo should be just a separate entity for each of the tables (yes, exact duplicate like Com_VanInfo, Sup_VanInfo etc), unless VanInfo isn't shared between this entities (then relationships should be inverted, i.e. Com, Sup and Util should contain FK for VanInfo).
Your database basically need normalization and I think you're database should be on its fifth normal form where you have two tables linked by one table. Please see this article, this will help you:
http://en.wikipedia.org/wiki/Fifth_normal_form
You may also want to see this, database normalization:
http://en.wikipedia.org/wiki/Database_normalization

Resources