When I save an entity to the database I encrypt the values in an OnSavingChanges event handler. When the entity is loaded back from the database I'm using OnObjectMaterialized to decrypt the values.
This works great except that if I call save on one of the entities after its been materialized, the object context thinks that the entity has been modified and saves it back to the database.
So how do I reset the modified state such that it thinks that the decrypted values are the values in the database?
Related
In TypeORM, if we have a repository called repo, we can call repo.save([entity1, entity2]) to save new entities and/or update existing ones. Repository#save also returns an array of the saved entities.
Is the order of the returned entities guaranteed to match the order that was passed in?
For example, if I call repo.save([newEntity1, newEntity2, newEntity3]) (where each is a new entity without an ID), will I always get back [entity1, entity2, entity3], where each element in the output array corresponds to the respective element in the input array, but with an assigned ID?
In my testing, the order seems to match, but I want to be sure that it's guaranteed.
Repository documentation: https://typeorm.io/#/repository-api
Relevant passage:
save - Saves a given entity or array of entities. If the entity already exist in the database, it is updated. If the entity does not exist in the database, it is inserted. It saves all given entities in a single transaction (in the case of entity, manager is not transactional). Also supports partial updating since all undefined properties are skipped. Returns the saved entity/entities.
It's not clear what guarantees this provides about the order.
This question is now a curiosity, more than anything. Dates will be the end of me.
Using EF 6.
I am storing a date and in the same http request, pulling the object back out of the database.
When I look at the SQL which EF sends, the milliseconds of the date in question which are returned are the same as that which are stored in the db (expected behaviour).
BUT, when EF deserializes that into the object graph in memory, the milliseconds are different.
So, I save '2018-10-16 21:46:22.293'
SQL retrieves '2018-10-16 21:46:22.293'
EF deserializes to 2018-10-16 21:46:22.294 !
I created a workaround by hitting the db with a raw ADO.NET query that gets the exact date ('2018-10-16 21:46:22.293').
Even weirder, if I use a fresh DbContext and grab the whole object with that, the date is fine i.e. '2018-10-16 21:46:22.293'
So, it is only when I use the same DbContext that save the data, to retrieve the data that the date gets rounded (or something).
Anyone seen this weird behaviour? Is there a better fix than either raw SQL (ado.net) or a fresh DbContext?
Cheers
You can bypass the EF cache by appending .AsNoTracking() to your retrieval query.
If you create entity client-side through EntityManager.createEntity(), when exporting, breeze generates tempKeys and assigns them to newly created entities.
But some entities are created server-side, but not saved(just created with new operator). Breezejs client is making a query. EntityState of fetched entities is Unchanged. PrimaryKey Id=0, it was just created, but not saved to db.
When you make exportEntities on manager it does not generate tempKeys, and entity Id remains zero. I tried to manually set EntityState to Added on that entities before exporting, but still tempKeys are not generated.
Any ideas how to properly export not-saved entity which came from server-side?
I think Breeze only creates a new temp key when the entity is attached to the EntityManager with state 'Added'. So try this:
entityManager.detachEntity(entity);
entityManager.attachEntity(entity, breeze.EntityState.Added);
That should cause a new temp key to be generated.
I am keeping local entities in breeze cache, how can i delete them from the cache with out going to the server?
in the documentation it states
Deleting an entity
You delete an entity by changing its EntityState to “Deleted” like this:
1
someEntity.entityAspect.setDeleted(); // mark for deletion
setDeleted does not destroy the object locally nor does it remove the entity from the database. The entity simply remains in cache in its new “Deleted” state … as changed and added entities do. A successful save does delete the entity from the database and remove it from cache.
You can do this by detaching the entity from entity manager by calling manager's detachEntity method :
manager.detachEntity(entity);
The detached entity will eventually be garbage collected.
Refer to Breeze-Inside Entity
You can do
entity.setDeleted();
and then call
saveChanges method.
if you want to save it in DB.
if not want to go to server
manager.detachEntity(nameofYourEntity);
I'm using Entity Framework (DbContext with database first) with MVC. When user save from a form, I have a condition in the controller that send the entity to the update of insert method depending of some internal flag of mine.
When sending entity to the update method, I flag it to modified using context.Entry(myEntity).State = EntityState.Modified;, I call saveChanges() and everything work well.
When sending the entity to the insert method, I flag it to added using context.Entry(myEntity).State = EntityState.Added; but when calling saveChanges() I receive error about 2 fields that are required...
The problem is that thoses 2 fields are not empty and they effectively contain valid data just before saving... I have even try to force new values to thoses 2 fields just before saving but same error.
It may be usefull to mention that I'm using Devart DotConnect For PostgreSQL as db provider.
Any idea how to debug this problem?
EDIT:
Here is the error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
When looking for this EntityValidationErrors I receive the 2 following specific errors:
The flg_actif field is required
The user_creation field is required
As mentionned before, those fields are filled with data just before saving so I don't understand what is happening.
I'm using EF v4.0.30319 (system.data.entity=> v4.0 and EntityFramework=> v4.4)
EDIT2:
Just to clarify a little bit more: The entity I'm trying to insert already exist in database. The form show the data of this database row. When saving, I decide if I update the row (this work well) but sometime, I need to insert the edited row as a new register instead of updating it to keep an history of the change in database.
Could you verify if the EntityKey property is set or null on the items you are trying to save?
If it already has a key, the context is already aware of the item, and you should use Attach instead of setting the state to added manually.
EDIT: To summarise the point from below. It looks like what you are doing is inserting a new copy of a row already associated with a context. That is almost certainly your problem. Try creating a fresh object based on your original row (i.e. copy the variable values or use a copy constructor), then add that new object.
Additionally, you should not need to set the state manually on a newly added object. You are trying to force the state here because the context doesn't see that item as a new one.