How to get the orginal entity instance on the client side? - wcf-ria-services

Suppose I have an entity person which has been modified on the client side.
Then I want the original person before it was modified. How can I do that on the client side before I submit the changes?

You can get the original state of an entity with MyEntity.GetOriginal() - http://msdn.microsoft.com/en-us/library/system.servicemodel.domainservices.client.entity.getoriginal(v=vs.91).aspx

Related

EF Core tracking entities with same id multiple times

I simply want to update an industry property of a client object. To do so, I retrieve the client from the DB using a repository. This would result in my industry (example id:149) being tracked.
var client = await _clientRepository.GetAsync(request.ClientId, token);
ind = _db.ChangeTracker.Entries<Industry>().Count();
Then, I update the industry by calling SetIndustry with a new Industry with Id:149 (same as before).
client.SetIndustry(new Industry(149));
ind = _db.ChangeTracker.Entries<Industry>().Count();
At this point EF Core 2.1 throws an exception.
System.InvalidOperationException: 'The instance of entity type 'Industry' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
In this class I cannot access the DBContext so i can't play with the change tracker. I was wondering how I could work around this problem?
Thx
Seb
I just added AsNoTracking() to my document object when I created my document variable and it worked out. Try doing the same with your client object.

Breeze JS : Entity Errors preventing patch-up on the client

I my client application I am calling entityManager.saveChanges to send all currently changed entities from the client up to the server. Then in the BeforeSaveEntity event on the server I am performing some server side validation on each entity to see if it should be excluded from the save map. So for example, my entity may have a value for description that is too long. So I return false from BeforeSaveEntity, and generate a new EntityError which will then be added to the saveResult.EntityErrors collection. All of the valid records that haven't been excluded from the save map then save off successfully, and my saveResult is returned to the client. But because of this single entity error, the auto-patchup of the entities returned does not occur back on the client. I looked at the source and basically there seems to be a check that says if there is anything in the saveResult.EntityErrors collection, don't bother with the patch-up. But There was only 1 entity that purposefully wasn't saved, so I still want to be able to patch up the others. Is this behavior by design? I want to be able to exclude certain entities from the save (which I can do using the BeforeSaveEntity event), but there doesn't seem to be any way of then getting the entity errors back to the client using the inbuilt mechanism, without the full patch-up being abandoned.
Saves in breeze are transactional if at all possible ( some backend providers, like MongoDb are not because they don't support it.). This means that if any failures are experienced with any entities within a save bundle the entire save is reverted and an error is returned to the client. This is by design.

Add or update in Entity Framework, complex deserialized objects

We're creating a WebAPI using Entity Framework in MVC 4. Our client wants to send complex objects containing related objects - both new and updated. The root object maybe new or existing one too. The client generates primary keys - we're using Guids for that. So on server we really can't tell that we got an existing object update or a new one. What would be the best way to handle this situation? We need some sort of add or update functionality and it's not yet clear to us how to proceed with Entity Framework for this.
EF doesn't have any build in support for discovering changes in detached object graph. You either have to include some field into every object describing if the object is new, not modified, updated or deleted (you will also need similar behavior to track changes in many-to-many relationships). If you don't use such field you have no other way than querying database and comparing current DB state with data received from client to find what has changed.

Entity Framework Service Layer Update POCO

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.

Entity Framework and Temporary Objects

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);