iOS Core Data Persistence for related entity - iphone

In my core data object model I have two entities that are related with a one to many relationship.
Example:
table A can have many table B's associated with it.
My question is, when I add table B rows (with the object reference to Table A), do I need to independently save table B, or will the save of Table A also persist table B?
It appears that table B is being persisted when table A is saved.. but I cannot find any documentation to confirm this.. and I want to make sure I don't run the risk of losing data.
(Core Data saves are very slow.. and saving Table B data independently is a hog).

Don't think about tables. What gets saved is the managed object context, which translates into: any changes you've made to managed objects using that context.

Related

Entity Framework 5: RelationShips and Attached/Detached objects

I'm a bit confused how to work properly with many-to-many relationships in locally created objects.
I've prepared a small example to demonstrate the issue.
There are two tables and one mapping table:
And data in tables:
Entity Framework has created two tables and many-to-many relation:
Now run the application and load single student (with ID=1 and his classrooms).
If student was loaded from the database then everything is fine and EF gets 2 classrooms:
But in case user was created locally (with the same Id but changed Name) and attached to the EF then classrooms are not loaded (studentLocal variable).
The same situation if I try to load student from EF - it gets the local user (student variable has Name="xx") and no classrooms:
On the view user can change classrooms for student as well as change student properties so I need to update Student table and merge StudentClassroom table.
What is the best way to deal in this case? I don't want to load each
postback student entity again and again.
Is there a way to load
Classrooms for locally created Student which exist in the database?
How to merge StudentClassroom records? I know only one - load
existed records and new one and merge then either deleting all of
them and recreating from the new list either manually determining
which records should be deleted/updated/created. Is there a better
approach?
Your problem is that EF is not creating the right tables for your model. It should be creating 3 classes not 2. Probably the reason it isn't is that you don't have the relations set up properly in the database. If you are using SQL Server try using the diagram feature to check your relationships and Primary Keys are correctly set up before you set up the model.

How do I tell EF to ignore columns from my database?

I'm building my EF (v4.0.30319) data model from my SQL Server database. Each table has Created and Updated fields populated via database triggers.
This database is the backend of a ASP.NET Web API application and I recently discovered a problem. The problem is, since the Created and Updated fields are not populated in the model passed into the api endpoint, they are written to the database as NULL. This overwrites any values already in the database for those properties.
I discovered I can edit the EF data model and just delete those two columns from the entity. It works and the datetimes are not overwritten with NULL. But this leads to another, less serious but more annoying, problem... my data model has a bunch of tables that contain these properties and all the tables need to be updated by removing these two columns.
Is there a way to tell EF to ignore certain columns in entities across the entire data model without manually deleting them?
As far as I know, no. Generating the model from the database is going to always create all of the fields from the database table. Well, as long as it has a primary key it will.
It is possible to only update the fields that you want i.e. don't include the "Created" and "Updated" fields in your create and update methods. I'd have to say though, that I'd think it'd be better if those fields didn't even exist on the model at that point. You may at one point see those fields on the model and not remember that they won't get persisted to the DB.
You may want to look into just inserting the datetimes into those fields when you call your create() and update() methods. Then you could just ditch the triggers. You'd obviously want to use a class library for all of your database operations so this functionality would be in one place. To keep it nice and neat, you know?

EF CodeFirst: Mapping entities (one-many) to the same table

Lets say I have Customer, Order, OrderDetail classes in the business layer (It's a simplified version of my problem).
I have also an old (existing) database that has one global table where every row of the table contains the information of Customers-Orders-OrderDetails; for example:
CustomerID, CompanyName,Fax,OrderID, OrderDate,ProductID,UnitPrice,Quantity
(in this way there are duplicated information of a Customer in different rows).
In the future I'll have a new database (with different table Customers, Orders, OrderDetails), and I want to use the same program.
I want to use EF CodeFirst to mapping to the old database and in the future to the new database
Which is the best solution?
Design a business layer with a global class that contains the information of Customers-Orders-OrderDetails. So the mapping of this class
with the old database using EF4 in the data layer is trivial.
In the future I'll modify both business layer and data layer for the new database.
Design a business layer with Customers, Orders, OrderDetails classes. In this case is it possible to map these classes to the global table of the old database? How ? (the problem is that the Customer-Order is one to many).
In the future I'll modify only data layer for mapping the new database.
This will work for now and later you will have to modify everything working with a global class - it can be a lot of work.
It is not possible to map one table to three entities where two have one-to-many relation between them with EF.
Use third approach. Load one class as described in first approach but immediately convert result to three classes from the second approach. The reverse operation will be done in case of persisting changes. Wrap this code in single place - repository. Your application will use three classes and it will not have any knowledge about the way how they are persisted. Once you change the database you will only remove additional conversions from the repository and work directly with Customer, Order, OrderDetail loaded and persisted by EF.

is it possible to use more than one SQLite files in CoreData?

Hello fellow stackoverflow family members?
I know it is un-efficient to create one extra sqlite table in iPhone CoreData system. (X)
Currently, My app has one sqlite table but there are preset data to users to no need to waste parse time. But if I adding new entity in current structure of SQLite table, it wipes up the whole preset data. I haven't tried to use immigrate method but I don't think it wouldn't be just adding a new entity on the table. I'm thinking it also wipes up previous preset data.
Current Architecture of SQLite file.
entity : A
attributes : contains data
I want to keep A with attributes still contain data but also add new entity : B.
entity : A
attributes : previous contained data
(PLUS+)
entity : B
attributes : new data
Do I need to create extra persistence set to separately store entity B (create another SQLite file and use as storage) or Is there possible way to add entity B in current SQLite with no changes in entity A?
Thank you.
To directly answer your question: Yes, you can reference multiple SQLite files in Core Data. You'll want to use a unique persistent store for each one.
I don't understand the rest of your question though, so it may be likely that creating multiple persistent stores is not what you want at all.
I know it is in efficient to create one extra sqlite table in iPhone CoreData system.
This is untrue. Creating multiple entities (aka, tables, but that is abstracted away) can lead to much more efficient queries.
Currently, My app has one sqlite table but there is no need to change preset sqlite table but want to add some other attribute.
Just add the attribute to your entity. If your app has already been released or you want to maintain existing data, you'll have to set up a migration and/or turn on lightweight migration.
So commit with new attribute and update coredata is not valid. Because it flash off current data set and need to spend another hours to type manually.
This didn't make any sense to me. Can you clarify?

Can we use union of two sqlite databases with same tables for Core Data?

I have an iPhone Core Data app with a pre-populated sqlite "baseline" database. Can I add a second smaller sqlite database with the same tables as my pre-populated "baseline" database but with additional / complementary data such that Core Data will happily union the data from both databases and, ultimately, present to me as if it was all a single data source?
Idea that I had is:
1) the "baseline" database never changes.
2) I can download the smaller "complementary" sqlite database for additional data as and when I need to (I'm assuming downloading sqlite database is allowed, please comment if otherwise).
3) Core Data is then able to union data from 1 & 2. I can then reference this unified data by calling my defined Core Data managed object model.
Hope this makes sense.
Thanks in advance.
Core Data is designed to handle multiple data files via the – addPersistentStoreWithType:configuration:URL:options:error: method. This will allow you to combine all of the data files together and then access them via a single NSManagedObjectContext.
Your only issue, and it may not even be an issue for you, is that the store files cannot directly reference each other. Therefore you will need to reference data between files "manually" via unique identifiers. However I suspect you are already aware of that limitation.
Manual Relationships
The idea is that when both objects in a "relationship" are in one model and one file, Core Data does its magic and handles all of the referential integrity for you. However when they are in different files and/or models this doesn't happen automatically anymore.
The solution to this issue is to use a fetched property that looks up some unique identifier to retrieve the entity (or entities) that you want to be on the other side of the relationship. This will give you a "weak" relationship between files.
One thing to note though when doing this. The fetched property does not get updated automatically when something changes. This means when data changes that would cause that relationship to change, your application will not be automatically made aware of it and you will need to request that property again to get the updated relationship information.
Hopefully that makes it a bit clearer.
Co-existance of fetched properties and relationships
They can definitely co-exist but realize that they are two separate properties. If you want your controller code to see them as one, then I would suggest building a subclass for that entity and then adding a convenience method in there that hits both the relationship and the fetched property and then rolls them up into one NSArray or NSSet before returning it back to your controller code.
You can attach the downloaded database with ATTACH DATABASE statement and operate with unions of tables.