I have a question about the coredata relationship.
Essentially, if I have 1 entity called i.e parent and the other entity which it has a relationship with is children and it is inverse.
If I create the parent entity, will it create the children entity as well? I 've set the "parentchildrenrelationship" to optional but it looks like every time I create the parent entity, it creates the children entity.
Is that something normal ? Thanks
It is not normal. Are you sure you're not creating the children entity otherwise? Just because you create one entity does not mean it creates the entities that it is referencing.
Core Data should not automatically create entities to fulfill relationships, especially if the relationship is optional. The value of children should either be nil (for a one-to-one relationship) or an empty NSSet or NSArray (for a one-to-many relationship, depending on ordering) for a newly created parent entity.
Related
I´m using EF databaseFrist and creating a model, now having a problem trying to understand how to delete an entity or a relationship.
Lest say a have and Table "A" and a Table "B", and a "a_b" table that relates A and B by id (many to many), a_b only has id_A and id_B, so there is no entity a_b created on the model. A has a list<B> and B has a list<A>, i need to know how can i perform the next functions:
-Remove all B entities related to A, it means delete the rows of B.
-Remove only the relationships of A to B, so all entities still exist on DB but they are dissociated.
-Delete A and remove all B related as well (remove entities from DB).
-Delete A and preserve all B entities.
-How will it change if a_b has any other property so it becomes an entity
thanks for your time.
pd: I´m using Lambda syntax.
You can tell EF on DB First model creation to expose all primary and foreign-key properties in the entities. What it means to you is that you can query separately by querying for child objects to a parent by using the foreign-key property of the child object linked to the parent object's primary key. You can delete each child object to the parent by the child's primary-key property value to remove the relationship between parent and child. You can delete the parent if no child object is linked to the parent. That's if one is doing things normally in a deletion process using EF where one takes complete control of the deletion process.
So, you can kind of do something like that.
When working with a one-to-one relationship at the database level, we (I?) often end up implementing what is actually a one-to-many relationship.
For example:
CREATE TABLE master (masterId INT PRIMARY KEY)
and
CREATE TABLE child (
childId INT PRIMARY KEY,
masterId INT,
CONSTRAINT child_master_fk FOREIGN KEY (masterId) REFERENCES master (masterId))
While a single child can only reference a single master, there is nothing preventing multiple childs from referencing the same master, resulting in a one-to-many relationship.
When generating an entity data model from such a database set-up, this gets reflected with the fact that the master entity will contain a reference to the child entity, but the child entity will have a master entity collection.
Since I logically see the relationship as one-to-one, I never expect the child's master collection to contain more than one element; thus, I'd like the child entity to have a single master reference instead of a collection.
What is the correct way of accomplishing this? Creating a two-way foreign key constraint at the database level? Tweaking the generated model?
Tweak the model. Add a singular reference property that returns the single instance and just ignore the collection property. Then set the singular property to be ignored by EF in your mapping configuration.
It isn't what I'd call elegant, but such sacrifices often have to be made when using EF with a pre-existing database.
I'm using this trick to perform conditional Include's with EF. http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx
The problem I'm having is that any collections that don't have records, are null, and not empty. This is causing headaches cos I have to check each collection before I can loop through it in my mvc view, otherwise i get a null reference exception.
For example, the StudentModules collection will be null. How can I turn it into an empty list in my query? ie without having to loop through it all and checking.
I can put a constructor in the poco to initialize the list, which fixes it, but the this collection is a virtual member in the poco (based on an EF video!) - surely this is not the way to go?
var query = from module in db.Modules
where module.Id == id
select new
{
module,
QualificationModules = from qualificationModule in module.QualificationModules
where qualificationModule.IsDeleted == false
select new
{
qualificationModule,
qualificationModule.Qualification,
StudentModules = from studentModule in qualificationModule.StudentModules
where studentModule.IsDeleted == false
select new
{
studentModule,
studentModule.Student
}
},
Assessments = (from assessment in module.Assessments
where assessment.IsDeleted == false
select new
{
assessment,
assessment.AssessmentType
}
)
};
var modules = query.AsEnumerable().Select(x => x.module);
return modules.ToList().First();
Relationship fixup runs when an entity gets attached to a context - either manually by calling Attach or when the entity is materialized as a result of a query (your case).
It is based on foreign keys of an entity and works in both directions:
If the context already contains an entity A with a foreign key f to entity B and an entity B is being attached to the context that has a primary key with the same value f as the foreign key in A (i.e. the two entities are related by an FK relationship) then Entity Framework will do the following:
If A has a navigation reference property to B it will assign the attached entity B to this property.
If B has a navigation reference property to A (one-to-one relationship) it will assign A to this property.
If B has a navigation collection property to A (one-to-many relationship) it will add A to this collection in the attached entity B. If the collection is null it will instantiate the collection before adding.
If an entity B is being attached to the context that has a foreign key f to an entity A that the context already contains and that has f as primary key EF will set the navigation properties based on the same rules like above.
As a side note: The fact that relationship fixup is based on foreign keys (they are always loaded when you query an entity, no matter if the FK is exposed as property in the model class or not) is also the reason why relationship fixup does not apply to and does not work for many-to-many relationships because the two entities of a many-to-many relationship don't have a foreign key.
Now, if there are no related StudentModules in your case there is no StudentModule entity that gets loaded into the context and there is nothing what EF could target for a fixup. Keep in mind that the fixup algorithm is not related to a particular query and does not only fix relationships between entities that this query would materialize but it will consider all entities for fixup that the context already contains, no matter how they came into the context. If you would want that collections get instantiated as empty collections EF had run through all attached parent entities of StudentModules and just create an empty collection. It makes no sense to do this during fixup instead of creating empty collections up-front before entities get attached to a context.
I can put a constructor in the poco to initialize the list, which
fixes it, but the this collection is a virtual member in the poco
(based on an EF video!) - surely this is not the way to go?
In my opinion it is the best solution if you don't want to have null collections in your model class instances. It doesn't matter if the collection is declared as virtual (to enable lazy loading) or not. A collection type does not have a derived proxy type, only the instances that get added to the collection are derived proxies. In both case you can just use StudentModules = new HashSet<StudentModule>(); (or List if you prefer).
I have a case where i have three entities with one-to-many and one-to-many relationships:
Entity A (Entity B relationhip),
Entity B (Entity A relationship, Entity C relationship),
Entity C (Entity B relationhip)
I have the reference of Entity A, and now i want to fetch all the related Entity C records. How can i do that? (with least amount of code)
Edit: Here's another way to put it.
Can we perform joins with CoreData. For example, (and this is a very crude example), We have a following entity-relationship:
Grand Parent (1)---(m) Parent
Parent (1)---(m) Child
So, now if i have "Albert" the Grand Parent, and i want to get all his grand children, how can i do that?
In case someone else stumble across a similar situation, here's what worked for me:
NSArray *allFieldValues = [myEntityA valueForKeyPath:#"Entity B relationship.Entity C relationship.requiredFieldInEntityC"];
I was mainly interesting in reading the data of a single field in Entity C (that's linked to myEntityA object). The key concept here is that "don't think of CoreData as a 'database'".
I am trying to import data from a database that uses primary key / foreign key relations to a core data database in Xcode.
I have code that creates hundreds of child entities in a managed object context:
Each child has an ID that corresponds to a parent.
child1 parentID = 3
child2 parentID = 17
child3 parentID = 17
...
childn parentID = 5
I now need to relate each child to its parent. The parents are all stored in persistent memory.
My first thought was to preform a fetch for each child to get its parent. However, I think this would be slow.
Am I correct? How should I do this instead?
Why are you modeling this parent-child relationship using an attribute in the child entity?
You should model this using a to-many relationship from the parent entity to the child entity, and a to-one inverse relationship from the child to the parent entity. Set on delete cascade on the to-many relationship and nullify on the to-one relationship.
Then, once you have a child object you simply use the to-one relationship to the parent entity to access the child's parent.
I have been looking at a few examples and have decided that the best approach would be the following
1) Fetch all the parents
2) Transfer them into a dictionary with their parentID as the key
Then for each child, look up its parent in the dictionary, then relate them together.