CoreData: Create a new entity to be parent of old entities - ios

Recently, I am trying to refine my code. I found that all my entities has attributes named identifier and owner, so I want to create a entity to be their parent which contains identifier and owner.
Following is the result, all object inherit from a parent named SRModel, which has identifier and owner attributes.
However, after I delete all these redundant properties, the persistent store is not able to auto migration.
How can I solve the problem? Do I have to do migration by myself?
Are there any simple way to do so?

According to Apple's Core Data Model Versioning and Data Migration Programming Guide, you can't do that automatically.
You cannot, however, merge entity hierarchies; if two existing entities do not share a common parent in the source, they cannot share a common parent in the destination
Note Andy Riordan's point about inheritance. And don't just take his word for it; look at the generated .SQLite files yourself under the old and new models. Adding a parent entity with only two common attributes will just make your entities, and backing tables, larger, with no performance benefit. If you really want to note the two common elements, use a Protocol to call them out.

Related

iOS - How to migrate 2 Entities into 1 using Core Data?

In my current model version I have this 4 Entities :
Satellite (with relationship to one to SatelliteAnimation)
SatelliteAnimation
Radar (with relationship to one to RadarAnimation)
RadarAnimation
In my App I have different blocs in which I display information.
This is why I have entities RadarAnimation and SatelliteAnimation, in order to recognize those blocs by type.
Anyway, my issue is that I want to migrate 2 blocs in 1.
And instead of having 4 Entities, I would like to have :
Radar
Satellite
Animations
I don't need the relationships anymore.
I know I can rename an Entity in a lightweight migration process.
What I would like to do is :
Create a new data model version
Delete the SatelliteAnimation entity
Delete the relationship between Satellite and SatelliteAnimation
Delete the relationship between Radar and RadarAnimation
Rename the entity RadarAnimation by Animations
Set the new data model version as current model version
Does this way of handling my issue will affect the migration process ?
Can I rename and remove relationships in a new data model version ?
This should be possible with automatic lightweight migration. Deleting entities and relationships just works with no extra steps, so that's fine.
To rename something you'll use the renaming identifier in the model editor. After you create the new version of your model, select the entity you want to rename in the model editor. Change its name but set the renaming identifier to the old name. In your case, change the entity name from RadarAnimation to Animation, but then also set the renaming identifier on the entity to RadarAnimation so Core Data knows what it used to be called.
Incidentally attributes and relationships can also have renaming identifiers, so they can also be renamed this way.
Apple provides detailed documentation on what can be done with lightweight migration which will probably be useful as you go through this.

Core Data Relationships are not migrated (Custom Migration)

I really don't know where else to search for a solution to this problem. Basically, I've read twice (or more) all documentation and all pages I found on the web about Core Data Migration.
I had to change some names on the Entities (to readability) and also had to change the domain values used in my entities. AFAIK, in this case, I have to make a custom migration because I have to analyze the Input and generate a new Output:
I've created the new Model Version (v7)
I've updated the Model
Renamed existent Entities, Attributes and Relationships.
Added/Removed some Attributes
I've created the Mapping Model (v6 to v7)
I've configured the Mapping Model using Expressions
I've created two NSEntityMigrationPolicy (one for each entity)
The migration is going well for the entities and fields values, but none of the relationships are getting restored during the process.
During the process, the expression:
FUNCTION($manager, "destinationInstancesForEntityMappingNamed:sourceInstances:" , "RecentCallToRecentRecord", $source.recents)
is returning nothing.
I have debugged my custom NSEntityMigrationPolicy to check if the Source and Destination Entities are bound as expected and something very weird is happing. During the execution of createDestinationInstancesForSourceInstance:entityMapping:manager:error: everything is OK, after calling the superclass, I can navigate from Source to Destination (and the other way around). But during the execution of createRelationshipsForDestinationInstance:entityMapping:manager:error: this objects navigation does not work anymore.
Thanks in advance for any help.

Do i need a core data migration when i add a new model to my .xcdatamodeld file

i have a an .xcdatamodeld which already has 2 entities, i have added another entity into this file(am not sure whether this is the right way to add a new entity), anyways my question is, do i need to implement any kind of migrations to take care of users who already have the app installed on their devices.
Please note, i have not modified any columns or schema on already existing entities.
cheers.
You don't need to do migration if you just only adding new entity, assuming that it doesn't have relationship with the other. According to raywenderlich.com, you have to do migration for the following scenario:
Deleting entities, attributes or relationships.
Renaming entities, attributes or relationships using the renamingIdentifier.
Adding a new, optional attribute.
Adding a new, required attribute with a default value.
Changing an optional attribute to non-optional and specifying a default value.
Changing a non-optional attribute to optional.
Changing the entity hierarchy.
Adding a new parent entity and moving attributes up or down the hierarchy.
Changing a relationship from to-one to to-many.
Changing a relationship from non-ordered to-many to ordered to-many (and vice versa).

Create Core Data entities dynamically during runtime

I need to be able to create new core data entities during runtime. I've written the code to create the objects programmatically, however, I can't add the entities during runtime as the model is immutable.
My problem is similar to this post, however there is no satisfactory answer: How to dyanmic create a new entity (table) via CoreData model?
The documentation regarding changing the core data model explains:
Managed object models are editable until they are used by an object
graph manager (a managed object context or a persistent store
coordinator). This allows you to create or modify them dynamically.
However, once a model is being used, it must not be changed. This is
enforced at runtime—when the object manager first fetches data using a
model, the whole of that model becomes uneditable. Any attempt to
mutate a model or any of its sub-objects after that point causes an
exception to be thrown. If you need to modify a model that is in use,
create a copy, modify the copy, and then discard the objects with the
old model.
However, I'm unclear on what exactly this is saying--that the whole core data model can't be changed once the persistent store coordinator has been used or the attributes/etc of the individual entities can't be changed.
To be clear, I do not want to change the attributes of my current entities, I simply want to add new entities. It just seems weird to me to have to use migration to add new entities.
Any thoughts?
Thanks!
The documentation is pretty clear.
Copy the model.
Apply your changes to the new copy.
Destroy your old MOC, Persistent Store Coordinator, and all objects created from those.
Apply a migration, if necessary.
Create a new Core Data Stack (MOC, PSC, etc) using your updated model.
The migration could be a sticking point, but it should be do-able.

EntityFramework database vs model

I understand the fact that generating a model based on the DataBaseFirst method woill produce a collection of entitites on the ORM that are essentially mapped to the DB tables.
It is my understanding, that if you need properties from other entities or just dropdownlist fields, you can make a ViewModel and use that class as your model.
I have an AppDev course that I just finished and the author wrote something that if I understand it correctly, he is referring to change the ORM entities to fit what your ViewModels would look like, hence, no need for ViewModels. However, if you do this, and regenerate the ORM from the database, those new entities that you placed as "ViewModels" would be gone. If you changed the ORM to update the database, then your database structure in SQL Server would be "undone".
Please inform me if my understanding is correct that I simply need to use a ViewModel in a separate folder to gather specific classes and or properties in a superclass or a single class with the properties that I just need and use that as my model....
Here is the excerpt from the author:
EntityFramework is initially a one to one mapping of classes to tables, but you can create a model that better represents the entities in your application no matter how the data is stored in relational tables.
What I think the author may have been hinting at is the concept of complex models. Let's say, for instance, that in your Database you have a Customer Table and an Address Table. A one to one mapping would create 2 model items, one Customer class and one Address class. Using complex model mapping, you could instead create a single Customer class which contained the columns from both the Customer Table and the Address table. Thus, instead of Customer.Address.Street1 you could refer simply to Customer.Street1. This is only one of many cases where you could represent a conceptual model in code differently than the resulting data in storage. Check out the excellent blog series Inheritance with EF CodeFirst for examples of different mapping strategies, like Table Per Hierarchy (TPH), Table Per Type (TPT), Table Per Concrete Class (TPC). Note that even though these examples are CodeFirst, they still apply to Entity Framework even if the initial models are generated from a Database.
In general, if you use DatabaseFirst and then never modify the resulting entities, you will always have a class in code for each table in the database. However, the power of Enity Framework is that it allows you to more efficiently work with your entities by allowing these hybrid mappings, thus freeing you to think about your code without the extra burden of your classes having to abide by rigid SQL expectations.
Edit
When the Database-First or Model-First entities are generated, they are purposely generated as partial classes. You can create your own partials which extend the classes that are generated from Entity Framework without modifying the existing class files. If the models are re-generated, your partial classes will still be intact. Granted, using partials means that you have the Entity Framework default behaviors as well as your extended behaviors, but this isn't usually a huge issue.
Another option is that you can modify the TT files which Entity Framework uses to generate your models, ensuring that your models are always regenerated in the same state.
Ultimately, the main idea is that just because the default behavior of Entity Framework is to map the database to classes 1:1, there are other options and you are never forced into something that isn't efficient for your project.

Resources