Core data many to many parent child relationship - core-data

I apologize if this question exists already on the site posted a different way but after browsing I couldn't find anything.
I have an entity in core data called category which stores categories and subcategory objects. I would like to have create a relationship between categories and sub-categories. In my app, I have the following requirements:
sub-categories can belong to multiple categories.
Categories can have multiple sub-categories
A category will hold a list of its parents and children.
So really, sub-categories are just categories.
What I would like is to find a way to create my category entity to have that parent child relationship as well as a list of parents and a list of children for each category.
Can someone suggest an approach for this problem? would I need a "junction" entity? What would a fetch request look like to get a category object from the entity and populate its parents and children lists while taking advantage of the whole object graph concept (if possible)
Thank you.

Simply create the Category entity and add two relationships to itself: subCategories and parentCategories, which are of course each others reverse relationships. Now you can access the corresponding lists very simply:
NSSet *children = category.subCategories;
NSSet *parents = category.parentCategories;

Related

How to Add target NSManagedObject to another one with an inverse many-to-many Core Data relationship without duplicating target NSManagedObject?

I had encountered an issue one of my projects, I had spent dozen of hours to find the solution, I had made some progress, but still not getting what I would like to achieve ideally. I am still finding solutions myself now, while I would really appreciate anyone could share any insight for constructive solutions.
Issue:
How to add a target NSManagedObject from a master list as one object
of the references in another NSManagedObject with an inverse
many-to-many relationship between each NSManagedObject without
creating duplicate target NSManagedObject in the master list.
Note:
The following example used an analogy to the full data model graphs
to my real project. The analogy is what I can best describe the issue
I have, while the objects in the analogy do not fully share the same
name of the objects in the real project.
What I have now:
A master list of ingredient objects, which are unique among each
other.
A list of recipe objects, each of which would like to have different
ingredient objects to define the recipe object.
What do I want to achieve:
Ingredient objects can be inserted as multiple times into a single recipe object with each insert as unique count instead of making same ingredient being considered as one single count.
I did not want to duplicate each ingredient object inside of the
master list to be able to add multiple ingredients objects to each
recipe object or cross multiple recipe objects.
What I had tried:
Use Core Data to manage the ingredient and recipe as 2
NSManagedObjects.
Had created a relationship attributes called “allHostRecipes” on the ingredient managed object, and set it as “to-Many“ relationship to the recipe managed object
Had created a relationship attributes called “allUsedIngredients” on the recipe managed object, and set it as “to-Many“ relationship to the ingredient managed object.
These two relationships are set as “inverse”.
I had a Recipe Description View with a Table View that lists all the ingredients that are and will be included inside of the recipe.
I created another Ingredients Selection Table View that can be triggered in the recipe description view to pick each ingredient,which is going to be added into the recipe.
Each time when an ingredient is picked in the Ingredients Selection Table View, I call objectAtIndexPath(_:) on the NSFetchedResultsController that is for ingredients Table View from the ingredients’ master list to find the selected ingredient objects in its ManagedObjectContext.
Then I passed the selected ingredient managed object (SelectedIngredientManagedObject) back to Recipe Description View and called mutableSetValueForKey("allUsedIngredients").addObject(SelectedIngredientManagedObject) on the NSFetchedResultsController that is for fetching ingredients that is contained inside of a recipe object.
The “NSFetchedResultsController that is for ingredients Table View from the ingredients’ master list” and “NSFetchedResultsController that is for fetching ingredients that are contained inside of a recipe object” are separate instance variables in “Table Views of Recipe Description View” and “Ingredients Selection Table View”. But they referenced the same ManagedObjectContext.
What I had got now:
The selected ingredient managed object can be added to the recipe.
But, if I selected the same ingredient multiple times, it only get count once in the Table Views of Recipe Description View instead of showing multiple counts by each inserting, which is NOT what I want to achieve as described above.
My Question:
What should I do or adjust to achieve the functionalities that I had
to describe above?
What I think the directions to solve the issue:
What other things should I do when defining the “Many-to-Many”
relationship in Core Data model?
Does the fact that the “to-Many“ reference is using an NSSet cause the count issue?
Is it necessary to create multiple ManagedObjectContext to achieve the desired functionalities?
Should I clone the selected ingredient managed object as a new ingredient managed object? Which I had tried, and it will add duplicated ingredient to the ingredients’ master list. This is also NOT what I want. If I need to clone it, how can I make it right?
I really appreciate your time to view it, I am looking forward to having your insights. Thank you very much.
Regards,
Knight
You need to remodel the data slightly: Remove the many-many relationship from Recipe to Ingredient, and replace it with an intermediate entity (finding a good name is difficult, let's say RecipeIngredientDetails).
Create a one-many relationship from Recipe to RecipeIngredientDetails, say allUsedIngredientDetails, with inverse (to-one) recipe.
Likewise create a one-many relationship from Ingredient to RecipeIngredientDetails, say allHostRecipeDetails, with inverse (to-one) ingredient.
This addresses the problem with a direct many-many relationship, where each Recipe can be related to each Ingredient only once. (You are correct, this is in part a consequence of the relationships being modelled as Sets, which cannot have duplicate members). You have two options: you could just add multiple RecipeIngredientDetails objects, each related to the same Recipe and Ingredient pair. Each such object might represent a standard base quantity of the ingredient. Note that you could not have just one object for each Recipe/Ingredient pair, and try to add that object to the same Recipe multiple times: a given Recipe and a given RecipeIngredientDetails object can be related at most once.
But it might be better to add an attribute to the RecipeIngredientDetails, say quantity. You then only need a single such object for each Recipe/Ingredient pair, and can update the quantity attribute to reflect the amount of the ingredient that is appropriate for that recipe.
This is the approach mentioned in the CoreData Programming Guide section on Modeling a Relationship Based on Its Semantics:
For this sort of relationship, use an intermediate (join) entity. An advantage of the intermediate entity is that you can also use it to add more information to the relationship.
It is equivalent to adding a join table with foreign keys and additional columns to a SQL database. I'm not aware of any simpler way of achieving your objectives in CoreData - there is no way to directly add attributes to relationships.
Regarding the ordering issue that you mention in comments, you had added "a Double type attribute in the Entity to keep track of the order". If you have only two entities, and a many-many relationship, and you add the order attribute to the Ingredient then (for example) if "Flour" is the first ingredient for "Bread", it would have to be the first item for every other Recipe it is used in. In the approach I describe, you would add the attribute to the intermediate entity, RecipeIngredientDetails: the index (just as for the quantity) depends on both the recipe and the ingredient.
For indexes there is, however, another option I should mention: you could (in the data model editor) define the relationship from Recipe to RecipeIngredientDetails as ordered. The resulting property will be an ordered set (so you can insert, remove or move items to achieve the correct order).

Creating relationship among records in subgrids in CRM

I have two subgrids
Parent
Children
Now I will be adding entries to it from the contact entity
What I want to achieve is, I want to create parent-child relationship among the data that are there in these two subgrids so that I can use it for querying in future
Usage scenario:
I have a entity form for a entity called as MedicalCase
MedicalCase form will have two subgrids for "Children" and "Parent"
Now I will be able to add children and parent records to subgrid from the Contact entity
For these records in the parent and children subgrid, I want to specify, which parent is the father/mother of which child
I don't have the luxury of editing the Contact records, is there any other means that you can think of?
Someway in which I can record the relationship between child and parent in the subgrids
Hope I am clear enough, feel free to ask me if you need any clarifications
I'm having a hard time understanding the situation exactly, but after several re-reads it sounds like you need a custom many-to-many relationship entity. Create an entity called ChildParentRelationship (CPR) which should have a lookup to Child and a lookup to Parent. Your Medical Case form should have a sub-grid for CPR entity. When a user creates a new CPR record, they will specify the Child and Parent. Does that get you what you need?

How to define relationships between content items in Orchard CMS without select N+1

We currently have some parent child relationships between Orchard content items built using the Container/Containable structure.
The parent item is a manufacturer, the child item is a range, the child of a range is a product. We have this kind of parent child relationship 4 levels deep.
This is all working but on a page where we have a list of products from different manufacturers and want to display some information about the manufacturer with each product performance is terrible due to select n+1 issues.
This is because we are bringing in all the products in a single query, but then for each product a query is executed for the common part to find the container ID and then a separate query is executed for each manufacturer content item.
I've added query hints to get the common part eagerly, but we still have the select n+1 issue to get the actual parent content item, obviously at lower levels in the hierarchy this problem is magnified.
I think this is because of the lazy field for the Container on the CommonPart - I can't see a way of avoiding this with that structure, or telling the content manager to fetch it eagerly.
I then looked at defining the structure ourselves using http://docs.orchardproject.net/Documentation/Creating-1-n-and-n-n-relations#BuildingaRelationBetweenContentItems but the example there for relationships between content types again uses lazy fields to load in the parent.
What I want is to execute a single query to get me every product with its parent range and its parent manufacturer, but I can't see how to do this. Are there any examples of this?

NSPredicate for items in two-levels deep to-many relationship, w/o direct relationship

I'm trying to build a single NSFetchRequest predicate for the following (simplified) model:
There is a simple to-many relationship between a Category and a number of Brands.
Each Brand then has a modelNumbersData property which is binary data, a serialisation of an array of NSString modelNumbers which are exposed in a transient property on the Brand objects.
There is no direct relationship between Brands and Models. The relationship is that a Model's modelNumber may be in a Brand's modelNumbers transient property.
I would like to build an NSPredicate query to fetch all of the Model objects under a particular Category.
Fetching the Models for a Brand is easy, I can do "modelNumber IN $FETCH_SOURCE.modelNumbers". How do I now extend this query to originate with the category? It seems I need a SUBQUERY?
Furthermore, I am doing an NSFetchRequest, so unless I'm mistaken I need to start with "SELF.modelNumber IN (...)", so that we select from all Models.
Thanks in advance!
Ok, I got there first. For reference, the following works:
SUBQUERY(%#.brands, $brand, $brand.modelNumbers CONTAINS $modelNumber).#count > 0
I think the problem I was mostly having was neglecting the .#count component. Still don't quite understand this, but it seems to be necessary with all SUBQUERY statements.

BCS association of external entity to self

I have a BCS model in SharePoint. This model has a single entity that should have multiple child entities of the same kind. I tried to associate the entity to self but the association does not appear on the entities' forms in the list. I expect to have a user experience that is similar to having a lookup field in a generic list that looks up to the same list.
How can I implement this?
Thanks.
The best solution I found so far is to create 2 different entities, create an association between them and make these two entities return data from the same source (in my case a .Net class).

Resources