I have searched but I could not find any method that can do if data exist update, not add.
m_Context.AddRange(collection);
m_Context.UpdateRange(collection);
I can write these but I want to write below
m_Context.AddOrUpdateRange(collection) //no method like this
Is it possible?
Is there addOrUpdateRange method in EF Core 2.1?
No, there is no such method. Probably because there is no database-agnostic way to implement this that won't fail with a deadlock or key violation when multiple clients call it concurrently.
Related
I am trying to profile EF to understand more of its inner workings, I have tried to add two entities using the Add method and the AddRange method, then of course committing with the SaveChanges method. And here is what I got on the profiler in both cases.
Does this mean that EF actually makes two trips to the database one per insert? which means that if I am trying to insert 100 entities for example this will mean 100 trips to the database? which will greatly impact performance. or am I missing something here?
Yes, that is correct, it will issue one database call per item attempting to be added, as it is using the standard SQL INSERT command in this case.
The alternatives would be to use BULKINSERT, such as using a stored procedure that takes in an object such as a DataTable.
I was wondering if it is possible to override the ObjectContext.SaveChanges() method and write our own sql logic to save the changes made to the entities in the object context instead of relying on Entity Framework to save those changes in the database.
Generally you can do anything you want if you override SaveChanges and do not call base.SaveChanges but you will loose all the stuf EF will do for you. It means you will have to manually browse metadata and map your entities to SQL tables and columns. There will be like writing half the ORM yourselves.
If you just need some little custom logic when persisting entity you can map imported stored procedure to Insert, Update and Delete operations in the entity designer.
In EF4 SaveChanges(SaveOptions) is virtual. You can override this method. MSDN
#Ladislav is correct that a stored proc is one way to do this (+1).
Another way is to write a wrapper provider.
I'm looking for something like IEntitesFactory or something similar that allows me to handle the Entities instance creation.
Does anybody knows if it's possible with EF 4.0?
No there is no extension point to include your own entity factory. You can only handle ObjectMaterialized event for entities loaded from.
when persisting (updating) an entity you would call EntityManager.persist(entity) passing the complete entity. It is possible to intercept with #PreUpdate.
Does anyone have a recipe how to identify which properties have changed in this interceptor method ? Somehow comparing the old and the new entity ? Even better to implement a generic method instead of comparing field by field for each class.
Thanks for any input !
Sven
First of all, persist() is for new objects (insert) not update. Any object changed in the persistence context will be automatically updated.
JPA does not provide any standard way to know what changed. So you either need to track changes yourself, or use a JPA provider specific API.
In EclipseLink if you use the EclipseLink DescriptorEventListener preUpdate event instead of the JPA one, you get an ObjectChangeSet attached to the DescriptorEvent which contains the changes.
Another way in JPA, if you are using weaving, is to cast your object to ChangeTracker and call _persistence_getPropertyChangeListener() then getObjectChangeSet().
If you are using TopLink Essentials the descriptor events also apply, but change tracking was not weaved.
I'm new to the Entity Framework and am currently experimenting with it. I created a simple database, set up the model in VS2008, and have got the code going to query the database using the EF as well as inserting new data.
There's one thing that has me a little confused though. I have an entity (set up in my model) called Customer, and as part of the logic of my application I want to be able to create a temporary Customer object for some intermediate processing. This particular object should never actually be stored in the database. However, I noticed that as soon as I call SaveChanges() the customer is saved to the database. This isn't what I want to happen. I'd be quite happy to call AddCustomer() on the objects I do want to include - I just want to have the option to create a temporary instance for my own use.
I did discover I could call Detach() and pass in my temporary instance, which would stop it from being persisted. However I'm not sure this is the best way to do this since the temporary Customer object will have related objects, and unless I go through and detach them all I might end up in hot water.
It's possible I'm misunderstanding something about how the EF is supposed to work, or that I'm missing something obvious - I'm hoping someone can set me straight!
Thanks
John
If you want to have a temporary instance of an entity that'll never be connected to the EF again, use this Entity Cloner for cloning the entity
If you are trying to disconnect an entity, send it over the wire some where (let us say pass it over to the client over a service, to modify it, and then again get it back), and again merge back the changes to the EF - right now this is not directly supported. How ever, you can try these solutions
Entity Bag:
EFContrib (you need PostSharp4EF)
Why not have another Customer class with the same fields?
Just ran into this problem myself with a service using EF4 - there's a simpler solution - after you create the new entity instance, call
objectContext.Detach(newEntity);