I have two core data entities named Assignment and Question. Assignment entity has assignment details like its name, id etc. Question table has question name, id etc. Assignment has one to many relationship with Question. When I try to fetch the assignments details from server, I get assignment and question data and both Assignment and Question entities are updated in the core data store. Note that two different assignments might share same questions.
Now lets consider, assignment 1 has questions with id 1,2 and 3. Where as assignment 2 has questions with id 4, 5 and 1. In my question table it has only 5 entries as the question with id 1 is common in both the assignments.
I am using a NSFetchedResultsController to poulate this on the UI. I have an issue with fetching the questions in the same order it is added to the core data store(database)
For example: For assignment 2, I need questions in oder 4,5 and 1. There is no unique key using which I can create the sort descriptor.Without sort descriptor I can not create NSFetchRequest and without that it is not possible to create NSFetchedResultsController. Any thoughts on solving this issue?
To my mind, the best pattern would be to create a new entity, AssignmentQuestion, that has a has many-to-one relationship to Assignment and a many-to-one relationship to Question, as well as a sequence number attribute.
Assignment <--------->> AssignmentQuestion <<--------> Question
|--name |--sequence |--text
|--id |--id
|--etc. |--etc
Related
I am learning about ER modelling about Database systems. My problem is that there is a entity called books,enitity named user and I want to create a borrows relationship between user and book with attribute issue date. I modelled it as described but it was pointed that borrows cannot be a relationship because a same user can borrow a book twice. Can anybody explain me what this is as I am using issue data as an attribute so records in borrows relationship would not collide as I will use PK as userid,bookid and issue date. How can I model this accurately? I am a little confused in this.
In the ER model, entity relations consist of attributes of a single entity set, in which the PK identifies only one entity set. Relationship relations have a composite PK that represents two or more entity sets.
Your question uses a composite PK that represents two entity sets (userid and bookid) and a value set (issue date). Strictly speaking, it's neither an entity relation nor a relationship relation. It's a combination of a relationship relation (two entity keys) and a weak entity set (issue date functions similar to a weak key). If we want to be creative, we might call it a weak relationship.
If I was forced to draw an ER diagram for this, I might present it like this:
The ER model isn't a complete logical model (unlike the relational model) and there are some situations which aren't handled well or at all. This is one of those situations.
As per description, User and Book are the entities.
One user can borrow an instance of book.
Similary, one user can borrow multiple instances of book, whether It can be same
instance or various instances.
So every transaction between the User and Book has the Issue Date.
Neither the user nor the book has the Issue Date.
Here, the relationship between User and Book are Many to Many.
The Bridge table is Transaction. We can name it as Borrow also as per your interest.
Now, The user has one to many transactions.
Every Book has one to many transactions.
Every transaction is a combination of a User and Book.
Note: Since every user can have the same book multiple times and at the same day. So we can have a composite primary key of user_id, book_id and Issue_timestamp as there is a chance of redundancy in the Issue Date in the same combination.
If I'm making an Entity in Core Data to handle possible values a person can select in a questionnaire form do I have to create an attribute for every possible selectable question? For example my Entity named Person has attributes for name, date, time, and than a bunch of possible answers to select radio-button style that should be added to the Person Entity. Is it better to use a separate Entity for the questionnaire portion.
Edit for better clarity:
The app/survey form is a list of questions with a radio button style check box. If the question applies to them they touch the circle button and it fills in the circle. So its a boolean value. However I'm just not sure if I have to make each one of those questions an boolean attribute or not? This seems like a simple enough project to start learning Core Data which is the purpose of using Core Data instead of some other modeling and persistence solution.
If your properties are y/n answers, that would be boolean attribute e.g.:
Person.licensed = y/n
If your properties have more than y/n possible answer you might use a number attribute:
Person.licensed = 1(y), 0(n), -1(Unknown), -2(Ineligible)
You may need more flexible properties. Maybe there are many types of licenses:
Person.licenses --> Related Entity License with attributes- license.type, license.issueDate, license.expireDate
Then, if you are doing something like a survey, there are many other potential paths. You'll need to elaborate on what you are doing for more help.
Separating the two entities is a good idea as it avoids confusion and keeps your code cleaner. When you step away from the project and return to it 4 months later, there will be no issues discerning where data is saved and from where to retrieve it.
Your Person entity will have its attributes (name, email, etc) and the Questionnaire entity will have its attributes- yes, one for each question with a Boolean type.
Based on your comment you don't need a Boolean or any other attribute. You have a set of questions, which are just instances in the data store. You could group them into a questionnaire if you want, which would be another entity and a relationship between them. Your person is another entity, and has a to-many relationship to question. As the user ticks questions that apply to them you add those questions to the relationship.
I cant find in code first how to add id in sequence when one id was droped.
Example I have id 1,2,3,4,5 then I drop 3 and add another id but it has not 3 but 6 - how to change this. Help?
Ps. I use AddOrUpdate
This is intended functionality. Is there a particular reason your IDs have to be sequential??
This is pretty important for cascade deletion and referential integrity of relationships in EntityFramework. For example, say you have a bunch of objects related to a person object w/ id of 3. If you delete that person, then add another person w/ an id of 3, all of a sudden those other objects have a relationship with this new person object, which did not intend.
So really, don't be nervous about non sequential IDs, it should not affect your database lookup times.
if you have more questions comment below I'll try and explain.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm trying to understand how to model complex data relationships with Core Data.
With my app, I currently have an entity of Recipe, Ingredient and RecipeIngredient which bind ingredients to a recipe.
I have not come across any example of fetching data out of this joint entity. I'd appreciate it if someone could give an example of an entity like my RecipeIngredient in Swift.
The reason you haven't seen examples similar to your RecipeIngredient entity is that you don't need joint entities like that in Core Data. You're treating Core Data as if it were a relational database, where you'd typically use a join table in order to create efficient many-to-many relationships between entities. As explained in the Many-to-Many Relationships sub-section of the Core Data Programming Guide, with Core Data all you need to do is to specify a to-many relationship in both directions between two entities. Note the parenthetical remark in the docs:
(If you have a background in database management and this causes you concern, don't worry: if you use a SQLite store, Core Data
automatically creates the intermediate join table for you.)
Here's an illustration of the relationship as you should model it, ripped straight from Xcode's model editor:
If you'd still like to see examples of how to do this, search for something like "Core Data many to many relationships" and you'll find plenty. You could start here on StackOverflow; a quick search turned up a number of examples, including How do you manage and use "Many to many" core data relationships?.
Update: From your comment, I understand that you want to use an intermediate object to add information about the relationship between recipes and ingredients. That is a case where another entity is warranted. So let's say your model looks like this:
It seems unlikely that you'd want to fetch one of these RecipeIngredient objects directly; you'd probably just follow the appropriate relationship. So, you might create a fetch request to find all the Recipes whose name matches #"chocolate cake". (There are plenty of examples of fetch requests using a predicate in the docs and all over the net, so I won't do that here.) Your fetch request will return an array of recipes that we could call cakeRecipes, but you're probably only interested in one:
Recipe *cake = cakeRecipes.firstObject;
Now, what do you want to know about the ingredients for your cake? Here's a list of the ingredients:
NSArray *ingredientNames = cake.ingredients.ingredient.name;
If you'd like to log the ingredient names and amounts:
for (RecipeIngredient *i in cake.ingredients) {
NSLog(#"%# %#", i.amount, i.ingredient.name);
}
Or, you could use a fetch request to find the ingredients matching "celery", storing the result in celeries. After that, you might look for recipes including celery:
Ingredient *celery = celeries.firstObject;
NSArray *recipes = celery.recipes.recipe
If this doesn't help, perhaps you could be more specific about the problem. Also, I know you asked for Swift, but my fingers are still used to Obj-C, and the language specifics don't really come into play here -- Core Data works the same in both languages.
I recently asked this question about how best to retrieve and display in a tableview the titles my FRC is using for section headers.
Following a line of research suggested by #Mike Pollard in the second answer to my question, I ran across this question and was immediately struck by the similarity to my situation, and by the 4th answer, posted by #aroth.
Aroth's approach certainly appears sound, and I've created a new Category entity. Specifically, Category has a to-many relationship with Item, and Item has a to-one relationship with Category. However I'm having trouble understanding one aspect implicit in his proposed solution, and, more fundamentally, in this relationship:
In my case, both Category(s) and Item(s)--"Item" is called "ListActivity" in my case, but "Item" will do for illustration purposes-- will be named via two corresponding user input fields, which seems like it could result in multiple entries of the same name in the Category list.
My question:
How can I ensure that when I fetch a list of Categories that I get a singular instance of each category, i.e., one category per row in the tableview, with no repeats? Will Core Data automatically assign each new incoming Item to a singular instance of the appropriate Category via the relationship? Or will it somehow test for and winnow the list down to one entry per Category name upon receiving the fetch request? Or must the filtering be done with a predicate in the fetch request?
Thanks!
Core Data will do what you tell it to. This sounds like an issue related to you creating content in your data store rather than an issue with the FRC and table view. It's your responsibility to search for and reuse existing objects rather than creating duplicates and adding them to the store - indeed, only you (your code) knows what constitutes a duplicate.
So, basically, as you create new items, use a fetch request and predicate to find the suitable existing category (or suggest categories based on partially entered names). Then, either connect to the existing category or create a new one.