I have a view which includes data from multiple tables.
When I call that view, the results are loaded into the memory and stored. After I make some changes to the other tables which should effect the view, the view don't know anything about the changes.
So when I call that view again, for example a Get() method, EF returns the values of the stored data.
Of course I want the updated data. How can I force the view to get the data from DB and not from memory? Or is there a better strategy?
Better if I can make the view aware of the changes being made. Is this achievable with entity configuration, maybe by using HasRequired() method to map FK's?
EDIT:
I am using repository and unit of work pattern. So I am not creating and disposing a new context each time. Please consider this.
When you execute the Linq query on the view use AsNoTracking() extension method. This will force EF to always use data from database instead of memory:
var result = from x in context.ViewSet.AsNoTracking()
select x;
EF will not handle any automatic data refresh for you.
Related
Not sure why this just started happening, but I have a situation where an entity I am reading from the database doesnt contain the new values that were updated from a stored procedure before. I see the changes in the database after my stored procedure makes the update, and I also call UnitOfWork.Commit to save any other changes. I think make a call to get this item again, and the values are not the same as the ones in the database. Any reason for this? I am not grabbing this item anywhere before the update so I dont know how EF knows about it the first time I grab it after the update.
I'm going to guess Entity Framework is caching those values somehow. I would try using the Refresh() method to force Entity Framework to go back to the data store with RefreshMode.StoreWins to ensure the data store values win.
I moved some logic around so the item is updated before any EF calls.
I have a WPF app that has a grid with a list of data that I loaded with EF. Some other window can make changes to the same data loaded on the grid but using a different dbcontext instance. How can I see the changed data on the grid? I know I can refresh a single entity with ctx.Entry<MyEntity>(instance).Reload(); - but I want to see all the changes and no matter what I do, I only see the old values. I can't use AsNoTracking neither create a new DbContext instance in this case.
To me looks like a very simple case and I cannot see why EF don't just
update the values of the entities.
EF has this mechanism as well but it is not exposed on DbContext API. You need to get back to ObjectContext. If you just want to reload set of entities you will call:
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
objectContext.Refresh(RefreshMode.StoreWins, listOfEntitiesToReload);
RefreshMode.StoreWins causes all pending changes to be overwritten by reloaded values. You can also use RefreshMode.ClientWins which will keep your changes and merge them with reloaded data. The problem with this approach is that it only reloads entities you already have. You will not get new entities.
If you want to get new entities as well you must execute a query and you must tell EF that you want to reload values:
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
var objectSet = objectContext.CreateObjectSet<MyEntity>();
objectSet.MergeOption = MergeOption.OverwriteChanges;
var result = objectSet.Where(...).ToList();
Again MergeOption.OverwriteChanges overwrites all pending changes but you can use MergeOption.PreserveChanges to merge reloaded values to your edited values.
I think there can be still some issues with refreshing values with some relations and maybe also entities which were deleted in the database.
I just started looking at Database Views with Code First... and try to decide if I should use them.
Here Ladislav recommends to use NotMapped inheritance parent for table and Db-View (my view only adds sums of child entities)... but how this work with CF Migrations? I really want to use them.
Also... navigation properties will work on Db-View Entity?
Is there any way to save data directly into Db-View entity (and it's table)?
If you want to use code first and migrations you should not use views. Views are database "logic" constructs and code first is not an approach for creating database logic. With code first you should use the projection which is also mentioned in the linked answer.
Migrations will not be able to detect changes related to your views. You will have to write all migration code for views manually.
If you want to use views you should do database first (= no migrations) and either map them with EDMX or code mapping.
Also... navigation properties will work on Db-View Entity?
This is the only scenario where code mapping provides better support than EDMX. You can define relation in your model even if it doesn't exist in the database (but your database must ensure data integrity). It is in theory possible with EDMX as well but it requires changing EDMX manually.
Is there any way to save data directly into Db-View entity (and it's table)?
Yes but your view must be updatable. I don't think that view with aggregation values is updatable.
I would like to know when entities in a certain database table are either created or updated. The application is essentially a CMS, and I need to know when changes are made to the content so that I can reindex them for searches.
I know that the autogenerated LINQ to EF class has overridable methods for when certain fields change, but I need to know when the whole object is created/updated, not just a single field. I tried putting it in OnCreated, only to find that meant OnObjectInitialized and not OnObjectInsertedIntoDBTable xD
I did some searching and came across this link. The "Entity State" section looks like its what I want, but I'm not sure how to use this information. Where do I override those methods?
Or perhaps there is a another/better way?
(I also need to know this for another part of the system, which will send notifications when certain content is changed. I would prefer this code to execute automatically when the insert/update occurs instead of placing it in a controller and hoping hoping I always call that method.)
You need to get ObjectStateEntry(s) from the ObjectStateManager property of the ObjectContect.
var objectStateEntries = this.ObjectStateManager.GetObjectStateEntries();
This entries contain every object state you've pulled down per context and what kind of actions where performed on them.
If you are using EF4 you can override the SaveChanges method to include this functionality. I've used this technique to audit every change that occurs in the database instead of triggers.
I need to load an object from the database, modify some of its fields and relations, and then I want to store a new value for only one field, without modifying the rest.
It would look something like this:
var thing = db.Things.First();
thing.Field1 = "asdas";
thing.Field2 = 23;
thing.OtherThings.Add(new OtherThing());
thing.FieldToUpdate = doSomething(thing);
db.SaveChanges();
But that would save all the changes, what I want is to only save FieldToUpdate...
I've looked around and all I've found is to use stored procedures, which seems like too much for something that looks so simple, besides I would have to make a different stored procedure for each time I need to do something like this...
My current solution is to open another context, load the thing again, update the FieldToUpdate and SaveChanges, but that's both inefficient and ugly.
If you want to do this with attached entity you have to update FieldToUpdate FIRST and call SaveChanges. Than you can update other fields and call SaveChanges again if needed. No other way with attached entity.
Other way you can try is to detach entity, modify what you want to (it will not track changes). Then attach entity back to context and call:
// I suppose that db is ObjectContext or inherited type
db.ObjectStateManager.GetObjectStateEntry(thing).SetModifiedProperty("FieldToUpdate");
Now only FieldToUpdate is tracked as changed.
The Entity Framework is smart enough to figure out what has changed and what hasn't and optimizes the SQL statement is uses accordingly. If you only change FieldToUpdate, then the SQL statement will only be an update on the single field, not on everything.
However, if you do change Field1 and Field2 from what they were originally, they will be persisted too, but ONLY if they changed. Otherwise, there's no need to tell the DB to change it to what it already is.
Entity framework does it this way because that's exactly what the developer wants 99.9% of the time. If you are going to use an entity object as an object that you want to move around and manipulate in ways other than treating it as a model of the database (like it should be), then you may want to consider creating another new wrapper class that lets you mess with all the data fields that you want (and have others that aren't in there), and then have the save method of it do the proper entity framework persistance, to keep things separate and clean.