I wonder if anyone can help me?
I am having problems understanding why i need to issues DetectChanges on my POCO (non proxy) entities.
Of course i have this line to ensure that proxies are not returned.
context.ObjectStateManager.GetObjectStateEntry(order).State
And doing some research it appears if i need to check the "state" of an object then i need to issue detechChanges But why would i need to check the State of an object?
Basically I send along my POCO entity to a method that SAVES the data to a new ObjectContext (I create and destroy ObjectContext on each method)
Hence, i am having problems understanding why i would need to have ObjectContext track or be aware of changes?
Is it because that if its not aware if will not be saved?
Maybe i am miss informed but it appears that if i am using an existing ObjectContext (which i am not i am creating and destroying each time) that ensure ObjectContext is aware would be beneficial but otherwise not?
So in 1 method I am updating an object by creating a new datacontext, saving it to the db and destroying ObjectContext . Hence i am not using 2 methods, 1 method to send the update or new record and then another method for SAVING.
I would really appreciate any quick explaanations of why its needed?
Thanks in advance
Your question is little bit confusing. You are writting about Entity Framework but using DataContext which is related to LinqToSql.
The behavior differs in the way you are using ObjectContext. When you load POCO entity from database ObjectContext holds its instance in internal Identity Map. By default POCO doesn't use any kind of change tracking. When you save that POCO entity to the same instance of ObjectContext it internally calls DetectChanges to compare current entity state with stored state. This comparision defines which columns have to be updated. Internal call to DetectChanges is default behavior which can be turned off so you will have to call this method manually.
In your scenario you not using the same instance of ObjectContext. In that case you first have to Attach POCO entity to the ObjectContext. MSDN strictly says that when attaching entity it is marked as Unchanged. For that reason you have to say ObjectContext that entity has changed. You can do that for whole entity or you can define exactly which properties have changed but you have to do it manually = you have to store that information somewhere (Self tracking entities can help you with that but they have ohter disadvantages).
Related
What is the meaning of detached entity. In my course following in Spring Framework Guru. We made a DTO, Does it mean when you fetched data from db then convert it in DTO is it called Detached Entity?
A detached entity is an entity which state must not be reflected by the JPA provider.
In other words, if you change its state (i.e. through setters methods) these changes will not be saved to the underlying database, as the JPA provider doesn't have to "observe" such entities.
If entity E1 is a managed entity you can make it detached invoking (very reasonable named) method EntityManager#detach(E1). You can also use EntityManager#clear() which will clear whole PersistenceContext and effectively making all managed entities detached.
Some time ago I wrote a blog article on this general subject that helps to answer this question, and I post it here as a separate answer only because it comes at the subject from a slightly different perspective.
I am facing an issue: we have an ASP.NET Core 2.2 Web API project with EF Core 2.2. We are using default IOC framework to create the DbContext with scope lifetime. And we have a socket pipeline connected to our ASP.NET Web API service.
I find that when we change the data in the web frontend, the socket pipeline will always get the old result (we are using .FirstOrDefault() to fetch the data, it should not be the problem with first-level cache).
So I infer that it might be because of that the scope lifetime for DbContext, so I changed it to transient lifetime. And it works! We get the modified record.
I have two questions:
Is that behavior of DbContext by design? Or maybe I have some tricky issue in my code.
How much performance will the transient lifetime DbContext cost? Since maybe I will make every DbContext transient
1) Is that behavior of DbContext by design?
Yes
For each item in the result set If this is a tracking query, EF checks
if the data represents an entity already in the change tracker for the
context instance If so, the existing entity is returned If not, a new
entity is created, change tracking is setup, and the new entity is
returned
How Queries Work
2) How much performance will the transient lifetime DbContext cost?
Very little. Especially in ASP.NET Core, which has DbContext Pooling
Since maybe I will make every DbContext transient
But you shouldn't do that. Using a request-scoped DbContext is very useful. For instance you can use the DbContext in various layers of your application without having to pass one around, and you can manage transactions more easily.
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.
During the life of my ObjectContext, I receive a message saying telling me that a new entity has been added to the data source by some other process (i.e. not tracked by my ObjectContext). How do I add this entity to my local ObjectContext without recreating it?
I've looked at ObjectContext.Refresh() but I'm not sure if this is the right way forwards.
If the entity is available in your code, use the Attach method.
In case this object is not available in your code, the solution is indeed to call the Refresh method with StoreWins RefreshMode for the collection the object was added into.
I recommend you to take a look at the Self-Tracking Entities as well.
Is the answer not in the question title - long running object contexts are not a good idea in EF. Ideally the OC should be kept alive for as short a time as possible.
In ADO.net EF, when should you call the context.Attach() and the context.Detach() methods and how do these calls affect the data being returned or being inserted?
This is one of those questions where, "If you have to ask, you probably should not be doing it." The Entity Framework will implicitly attach entities in cases where it is obvious that this needs to happen. You really only ever need to explicitly attach and detach entities in cases where you are using more than one ObjectContext at once. Because this can be quite confusing, due to the implicit attachment which happens in the course of normal Entity Framework operations, I strongly recommend that people new to the Entity Framework use only one ObjectContext at a time. If you do this, you should never need to explicitly call Attach or Detach.
Calling, say, Attach does not really affect the data returned, insofar as it's scaler properties are concerned. But if it refers to other entities which are already loaded into the context into which it is attached, then these properties will be pre-populated without explicit loading. That said, entities returned from a query are already attached, so you cannot attach them.
Attaching Objects (Entity Framework)
http://msdn.microsoft.com/en-us/library/bb896271.aspx
Detaching Objects (Entity Framework)
http://msdn.microsoft.com/en-us/library/bb738611.aspx