I've a question regarding the IDataProvider and the model method. The wicket guide says that you can wrap the item in a detacheable model to prevent them from beeing serialized. If I wrap the model object directly in a loadabledetacheablemodel it is still serialized. It will not detached. If I get only the Id and retrieve it again (e.g. from the databse) each item will retrieved again which already loaded in the load method. Makes the usage of the LDM in an DataProvider any sense? Is there a way to detach all objects with only one query to the databse in the load method?
I've seen some other posts here regarding this problem but none of them satisfied me...
Thanks!
Take a look at ContactDataProvider/DetachableContactModel in wicket-examples.
Related
Hi
If anyone could please elaborate the difference between the three, i am new to EF and sometimes MergeOption.NoTracking happens to work whereas sometimes ObjectContext.Detach, but i never get the gist of it.
I would like to know Which situations should i use them. Also, if there is an object graph attached to some entity (either by firing the Include function or by calling EntityReference.Load()) What should be called if
1.) i don't want other objects attached to the entity
2.) i want all objects referenced by the entity
Any help would be greatly appreciated.
Regards
Hiren
MergeOption.NoTracking is used to improver performance for loading entities which will not be modified. Entity is in this case is not tracked by the context but it is still attached and lazy loading works.
ObjectContext.Detach completely removes entity from object context scope so the entity is not tracked and lazy loading doesn't work.
IEntityWithChangeTracker.SetChangeTracker is imho more like infrastructure for EntityObject. It is heavily used inside EF when entities are materialized and attached to the context.
I am using the Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects approach, and I am having a hard time with updating entities.
I am using AutoMapper to map my Domain Objects to my View Models and that works good for getting the data, no how do I get that changes back into the database?
Using pure POCO objects, I would assume that there is no sort of change tracking, so I see my only option is to handle it myself. Do you just make sure that your View Models have the EXACT same properties as your Domain Objects? What if I just change a field or two on the View Model? Won't the rest of the fields on the Domain Object get overwritten in the database with default values?
With that said, what is the best approach?
Thanks!
Edit
So what I am stumbling on is this, lets take for example a simple Customer:
1) The Controller has a service, CustomerService, that calls the services GetCustmoerByID method.
2) The Service calls into the CustomerRepository and retrieves the Customer object.
3) Controller uses AutoMapper to map the Customer to the ViewModel.
4) Controller hands the model to the View. Everything is great!
Now in the view you do some modifications of the customer and post it back to the controller to persist the changes to the database.
I would assume at this point the object is detached. So should the model have the EXACT same properties as the Customer object? And do you have to make hidden fields for each item that you do not want to show, so they can persist back?
How do you handle saving the object back to the database? What happens if your view/model only deals with a couple of the fields on the object?
If you're using EF Code First, i.e: the DbContext API, then you still do have change tracking which is taken care of by your context class.
after making changes to your objects, all you have to do is call SaveChanges() on your context and that will persist the changes to your database.
EDIT:
Since you are creating a "copy" of the entity using AutoMapper, then it's no longer attached to your context.
I guess what you could do is something similar to what you would in ASP.NET MVC (with UpdateModel). You can get the original entity from your context, take your ViewModel (which may contain changed properties) and update the old entity, either manually (just modified properties), or using AutoMapper. And then persist the changes using context.SaveChanges().
Another solution would be to send the model entity as [part of] the ViewModel. This way, you'll have your entity attached to the container and change tracking will still work.
Hope this helps :)
You are absolutely right that with a detached object you are responsible for informing the context about changes in your detached entity.
The basic approach is just set the entity as modified. This works for scalar and complex properties but it doesn't work for navigation properties (except FK relations) - for further reading about problems with navigation properties check this answer (it is related to EFv4 and ObjectContext API but same problems are with DbContext API). The disadvantage of this approach is that all fields in DB will be modified. If you just want to modify single field you still have to correctly fill others or your database record will be corrupted.
There is a way to explicitly define which fields have changed. You will set the modified state per property instead of whole entity. It is little bit harder to solve this on generic approach but I tried to show some way for EFv4 and for EFv4.1.
I agree with #AbdouMoumen that it's much simpler to use the model entities at the view level. The service layer should provide an API to persist those entities in the data store (db). The service layer shouldn't dumbly duplicate the repository lawyer (ie: Save(entity) for every entity) but rather provide a high level save for an aggregate of entities. For instance, you could have a Save(order) in the service layer which results in updating more basic entities like inventory, customer, account.
I'm after some opinions \ best practice for handling updates to my repository in the following scenario:
I am using EF 4 with the POCO tt templates which creates nice clean clr objects.
For example's sake lets say I have a POCO object name Customer and a ViewModel called CustomerViewModel. CustomerViewModel has a public property for the Customer object which is populated with the POCO Customer object.The view references the Customer object on the CustomerViewModel. So far so good. Everything is displayed as expected.
When it comes time to update the CustomerViewModel is passed back and only the properties that were bound to the view are populated, fair enough.
What I have now is a POCO object that is missing some of the property values which are needed to update via the EF data context. For example, since I did not display the ID in the view, it was not hydrated back into the view model's Customer property. Not really surprising behaviour but I am wondering what the best way to handle this scenario is.
So here is the question:
Would it be better to map the properties that i don't display into hidden fields so that I have the complete POCO object on postback which is ready for updating to the Repository? (I'm thinking there is needles sending of data to and from the client here)
OR should I do a read of Customer before my update(assuming I have the ID) and then update the properties from my view model object. ( is this a needles read on the database ?).
OR is there another may altogether that I am missing.
I realise that maybe there is no one correct answer for this but I'd be interested to hear how others are handling this scenario.
Thanks
I'm going to answer my own question here... maybe it was a silly question but the act of writing it out has made the answer more obvious..
The first option of populating hidden fields is a bad idea for too many reasons!! So I think I'll have to go with doing a read of the customer object on the post back and calling.
TryUpdateModel(customer, "Customer");
Where customer is the freshly read Customer and "Customer" is the property name on the view model.
It seems that this results in more data access than in a classic ASP where the object could have been shoved (rightly or wrongly) into Session !
Anyone care to add their 2c ?
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 have a requirement to only save data to a table in a database (I don't need to read it)
If the record already exists I want to update it otherwise I will add it.
It usually exists.
My entity context might already hold the object .. if it does I want to find it and use it again without causing it to refresh from the database when I 'find' it
i.e. The context holds a collection of entities (rows of a database) I want to find an entity in the collection and only want the context to go to the database if entity is not in the collection. I don't care about the current values of the entity .. I just want to update them.
Hope this is clear ..... thanks
I may not be quite seeing the question, but I believe your looking for some sort of caching mechanism, I know for work we use devForces IdeaBlade which does the trick, however I believe you can create a simple caching mechanism custom to you needs.
Link
The bits on caching will be helpful, if this doesnt help tell me and I can dig a little deeper.
I believe you need to use GetObjectByKey() instead of using an ObjectQuery I believe an ObjectQuery always hits the backend datastore whatever it may be.
More Info here http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.getobjectbykey.aspx