I would like to contact the stakeholders who submitted restitution that they do not directly use SQL or SProc, and present the following facts to him:
- Updates in ORM (for example, an entity infrastructure) work this way: you load the object that you are executing, you save the object. This is the only correct way.
- Obviously, in your case, this will mean downloading 1M objects and performing 1M updates separately (EF does not have batch processing of commands - each command runs in its own opposite direction to DB) - usually an absolutely useless solution.
- The example you provided looks very interesting, but for Linq-To-Sql. Not for Entity structure. If you do not implement it, you cannot be sure that it will work for EF, because the infrastructure in EF is much more complicated. Thus, you can spend several person days doing this without any results - this must be approved by the interested party.
- A solution with SProc or direct SQL will take you a few minutes and it will just work.
- In both solutions you will have to deal with another problem. If you already have materialized objects, and you will run such a command (through the specified extension or through SQL), these changes will not be reflected in the already loaded entities - you will have to iterate them and set the flag.
- Both scenarios break down the unit of work because some data changes are performed before the unit of work is completed.
It's all about how to use the right tool for the right requirement.
Btw. you can avoid loading real tables. This is just a query that you run. Do not use Include and do not access navigation properties (in case of lazy loading), and you will not load relations.
You can select only Id (via projection), create a dummy object (set only id and and flag to true) and perform only flag updates, but it will still perform up to 1M updates.
using(var myContext = new MyContext(connectionString)) { var query = from o in myContext.MyEntities where o.Flag == false select o.Id; foreach (var id in query) { var entity = new MyEntity { Id = id, Flag = true }; myContext.Attach(entity); myContext.ObjectStateManager.GetObjectStateEntry(entity).SetModifiedProperty("Flag"); } myContext.SaveChanges(); }
In addition, it will only work in an empty object context (or at least not a single object from the updated table can be bound to the context). Thus, in some scenarios that run before other updates, you will need two instances of ObjectContext instance = manually DbConnection or two database connections, and in the case of transactions = distributed transaction and another performance hit.
source share