Exclude Models from being saved with Breeze - breeze

I have EntityA which has a navigation property to EntityB. In the frontend it's possible to create a new EntityA and append it to EntityB. If I now try to save the new created EntityA, Breeze also want's to save the changes on EntityB (containing the new ID of the newly created EntityA). Is it somehow possible to avoid having EntityB, because in this specific use case it should be possible to append new entities to EntityB, but these should not be saved back (and also not be reported as pending changes)?
I see the possibility with using two EntityManagers, but this would mean that I can no longer have navigation properties between the two types.

Pascal is asking an important question: are Entity A and Entity B related one-to-one? More to the point are they related one-to-one such that A depends on B (i.e. A is a child of B)?
A typical relationship of this sort is the "extension" entity. Consider "Order" and "OrderExtension". "OrderExtension" is a bolt-on type with optional fields that "extend" the core order data. An order can have zero or one "OrderExtension" records.
Order is the parent in this example; it SHOULD NOT have a FK reference to the OrderExtension. The OrderExtension is the child and it SHOULD HAVE a required OrderID FK field. The parent Order can exist without a child, but the child OrderExtension cannot exist w/o the parent.
At least that's how I think it should be. I've often seen folks turn this around. They give the Order an OrderExtensionID FK field which is optional. The OrderExtension has no backpointer to the Order.
The weakness of this design is that it allows you to create multiple orphaned OrderExtension entities that don't belong to anything ... and you'll rarely know they are there.
I'm betting that's your situation. I'm betting that Entity B is like OrderExtension and Entity A is like Order. When you created the OrderExtension (B) and associated it with an Order (A), Breeze tried to maintain that relationship for you by updating the Order.OrderExtensionID property. That puts Order (A) in a modified state.
DO not proceed until you've figured this out. While Jeremy is correct that you can save one entity by cherry picking the pending changes - you can save B without saving A -, you risk breaking the integrity of your data!
From a modeling perspective you've made Entity A dependent on Entity B. If you don't save A at the same time you save B, there will be no way for someone using the database to know that the two are related.
Next time you query for either of them, neither you nor Breeze will know they are related. You will be unable to navigate between A and B. I'm pretty sure that's not what you had in mind.

You can pass an array containing the entities you wish to save to the saveChanges method to restrict which entities are saved.
From the breeze docs:
saveChanges ( [entities] [saveOptions] [callback] [errorCallback] ) async
Saves either a list of specified entities or all changed entities
within this EntityManager. If there are no changes to any of the
entities specified then there will be no server side call made but a
valid 'empty' saveResult will still be returned.
Parameters:
[entities] Array of Entity optional The list of entities to save.
Every entity in that list will be sent to the server, whether changed
or unchanged, as long as it is attached to this EntityManager. If this
parameter is omitted, null or empty (the usual case), every entity
with pending changes in this EntityManager will be saved.

Related

Data model for enum with associated values

I'm trying to figure out what's the recommended way to implement enum with associated values in Core Data data model. Let's say I have a book entity and I want to save in database how I got the book, like:
it's bought by me (or other family members)
it's borrowed from someone (e.g., a colleague)
it's given as a gift by someone (e.g., a friend)
This would be an enum in swift:
enum WhereItCameFrom {
case Bought(who: String, date: Date, where: String)
case Borrorwed(who: String, date: Date, dueDate: Date)
case GivenAsGift(who: String, date: Date, forWhat: String)
}
I'm thinking to implement it in data model using inheritance , as below:
Introduce a parent entity WhereItCameFrom and define the above cases as its children entities.
Define a to-one relationship from Book to WhereItCameFrom. Its deletion rule is Cascade.
Define a to-one relationship from WhereItCameFrom to Book. Its deletion rule is Deny.
See the diagram:
I'm wondering if this this the right way to do it and I have a few specific questions.
1) What's the typical way to implement enum with associated values?
I think my above modal is good. But just in case, are there other better ways to do it?
2) Is entity with no attributes normal?
In above diagram, WhereItCameFrom doesn't have any attributes. At first I added a type attribute to it to indicate if it's a Bought, Borrowed, or GivenAsGift entity. But then I realized this information is implicit in its child entity class type, so I removed it. So the only purpose of the parent entity is to hold the relationship. Is this use typical in Core Data?
3) Will the old object be removed automatically when modifying relationship at run time?
Suppose I modify book.whereItCameFrom relationship value at run time. Its previous value is a Borrowed object. Its new value is a GivenAsGift object. Do I need to delete the Borrowed object manually (I mean, doing that explicitly in application code)?
I guess I should do it. But given Core Data is a framework helping to maintain data consistency in object graph, that seems awkward to me. I wonder if Core Data has some feature that can figure out the Borrowed object is not needed and delete it automatically?
Thanks for any help.
UPDATE:
In the third question, after the old Borrowed object is disconnected with Book object, is my understanding correct that, from the Borrowed object perspective, the peer object has been delete and hence the peer object's Cascade deletion rule is applied to the Borrowed object? If so, then it will be deleted automatically. I think the real question here is if deletion rule applies to relationship update or not. I'll do some experiments on this later today.
A few thoughts...
1) What's the typical way to implement enum with associated values?
I think my above modal is good. But just in case, are there other better ways to do it?
I can't comment on typical ways of implementing enums with associated values, but your model seems to make sense. One word of caution: if you search StackOverflow for questions regarding entity inheritance, you will find several answers advising against using it. The way CD implements subentities (at least for SQLite stores) is to add all the attributes of all the subentities to the parent entity SQLite table. That's handled for you "under the hood" by CoreData, but the SQLite table can potentially end up being very "wide", which can affect performance. I've never found it an issue, but you might want to have that in mind if you have lots of data and/or the entities are more complex than you indicate in the question. Subentities can also cause issues in some rare situations - for example, I've seen questions indicating problems with uniqueness constraints.
2) Is entity with no attributes normal?
It's unusual, but not a problem. However, as all three subentities have date and who attributes, it would be wise to move these from the subentities to the parent WhereItComeFrom entity. (Otherwise, as noted above, your parent entity table will have three columns for date (one for each subentity) and three for who).
3) Will the old object be removed automatically when modifying relationship at run time?
No. If you modify the book.whereItCameFrom relationship value at run time, with a GivenAsGift object replacing a Borrowed object, CD's graph management will ensure that the Borrowed object's book property is set to nil. The cascade rule does not prevent objects being "orphaned" in this way and you must manually delete the Borrowed object.

CoreData relationship confusion

Suppose I have two entity named Book and Publisher
1. Book has attribute :- writer, title.
2. Publisher has attribute :- name, type
I set a relationship :- Publisher to Book ( one to many and set it as inverse relation)
With relationship selected I can see in DataModal inspector a row called Delete Rule with three options 1. Nullify 2. Cascade 3. Deny
What these are and I want to delete Publisher entity only if I delete the last Book
Thank You in advance.
I'm just a beginner
:)
The docs do a good job explaining these delete rules
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html
Relationship Delete Rules
A relationship's delete rule specifies what should happen if an
attempt is made to delete the source object. Note the phrasing if an
attempt is made. If a relationship's delete rule is set to Deny, it is
possible that the source object will not be deleted. Consider again a
department's employees relationship, and the effect of the different
delete rules.
Deny If there is at least one object at the relationship destination
(employees), do not delete the source object (department).
For example, if you want to remove a department, you must ensure that
all the employees in that department are first transferred elsewhere
(or fired!); otherwise, the department cannot be deleted.
Nullify Remove the relationship between the objects but do not delete
either object.
This only makes sense if the department relationship for an employee
is optional, or if you ensure that you set a new department for each
of the employees before the next save operation.
Cascade Delete the objects at the destination of the relationship when
you delete the source.
For example, if you delete a department, fire all the employees in
that department at the same time.
No Action Do nothing to the object at the destination of the
relationship.
For example, if you delete a department, leave all the employees as
they are, even if they still believe they belong to that department.
It should be clear that the first three of these rules are useful in
different circumstances. For any given relationship, it is up to you
to choose which is most appropriate, depending on the business logic.
It is less obvious why the No Action rule might be of use, because if
you use it, it is possible to leave the object graph in an
inconsistent state (employees having a relationship to a deleted
department).
If you use the No Action rule, it is up to you to ensure that the
consistency of the object graph is maintained. You are responsible for
setting any inverse relationship to a meaningful value. This may be of
benefit in a situation where you have a to-many relationship and there
may be a large number of objects at the destination.

Core Data Model

I'm struggling with creating a suitable Core Data model for my app. I'm hoping someone here can provide some guidance.
I have two entities -- "Goals" and "Items". The Goals entity contains only a goal description, but any goal may have any number of subgoals, and these may extend multiple levels in a tree structure. Subgoals are to be contained within the same entity, so presumably the Goal entity will contain a pointer to "parent" which will be the parent goal of any subgoal.
There will also be an "Items" entity that contains a couple of text fields and a couple of binary items, and must be linked (ideally, by a unique identifier, perhaps objectID) to the particular goal or subgoal the item(s) are related to.
I am totally fumbling with how to set this model up. I know what attributes need to be in each entity, but the relationships, particularly between goals and "subgoals", has me stumped. I don't seem to be able to turn up any good examples of tree structures in Core Data on the Internet, and even the couple of books I have on Core Data don't seem to address it.
Can anyone here help an old SQL programmer get headed the right direction with these relationships in Core Data? Thanks.
Have you tried creating a one-to-many from Goal to itself, and a one-to-one from Goal to Item? The only thing I would worry about here is circular references.
Also, read Relationships and Fetched Properties in the CoreData Programming Guide.
Here is how it is done:
You set up a to-many relationship from Goal to Item in the model editor. Don't use any ids, foreign keys etc. This is old-fashioned database thinking - you can forget about it. Here we are only dealing with an object graph. The database layer is just an implementation detail for persisting the data.
Make two more relationships in entity Goal to itself: a to-one called parent, a to-many called subGoals. Make them the inverse of each other. Simple!
QED is correct, you can create a to many relationship on goal (call it subgoals) as well as a to-one relationship on goal (call it parentGoal) and set them as inverses to each other.
Then create another to many relationship (call it items) on the goal entity, with the inverse being a to one relationship on the item entity (call it goal). Then you're all set. You don't need to link items with a unique id, just add them to the items relationship.
Also note that if you did want to give items a unique id, do not use the objectID. The objectID should only be used as a temporary id as they are not guaranteed to remain the same. In fact they will change if you ever do a Core Data migration.
One way, though not really great, is to create a another entity, say subGoal, and each goal has one subGoal and each object of subGoal has many goal.

How to call submit operation twice in one process in Silverlight?

I am working with Silverlight application with MVVM Concept and Entity framework and having some trouble in inserting the values. Using SubmitChanges method to update, insert, or delete data.
All of the pending changes are submitted in one operation.
Is it possible to use SubmitChanges method twice in one process?
Because I have below requirement:
In First step am inserting data into Table B.
Second step am inserting data into Table A. Here Table A has FK relation to Table B. That's why I am inserting data(Table B) in first step only.
But problem is: submitChange method insert all pending changes at once.
I need to submit the data twice in one process.
Entity Framework will handle the inserts correctly only if you setup the relationships correctly. You do not have to worry about the sequence of the inserts. Entity Framework will sort that out automatically. As a test, open a new diagram of your database and you should see a one to one or one to many relationship between TableA and TableB. If you do not see this relationship, EF will not know how to do the inserts.
Entity Framework will infer the sequence. If you check your object just before the context inserts the record, you should see zero's in the identity columns of both Parent and Child objects. EF will hydrate these properties with the identity values once the record(s) have been inserted.

Efficient collection Update/Insert in Entity Framework

I have a similar challenge to this post: Batch insert/update with entity framework from a couple years ago, I was hoping that the story may have changed since then.
In short, I am running a RESTful service, and as such I'd like a PUT to be document-oriented and take an object along with a collection of child elements in. The child elements have a unique string that I can use for determining existence.
Unlike the referenced poster, I don't have a query requirement; all I want to do is be able to take in a collection of my child elements and perform an insert on the child table for any that aren't already there, and an insert or delete on the many-to-many table to account for the current state of the collection. Ideally, with some efficiency. I realize that I might end up doing this as a sproc, I just wanted to see if there's an EF-native way that works first.
To do this you must either know which items are new or you must query DB first and merge your received items with loaded items. EF will not handle this for you. Also be aware that there are still no batch modifications. Each insert, update or delete is executed in separate roundtrip to database.

Resources