Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you tell if an EF4 entity is new or an existing record?

In my application I have an entity which is being used essentially as a complex many to many between my User and Project entities. I am trying to determine how to figure out if my service layer needs to add the entity to the context or attach the entity (for updating an existing entity) and I am at a loss of how.

This is easy to determine for most of my entities because of the Int Id field, if it's zero the database hasn't given it an identity value yet. This is not possible if it's a composite primary key.

Does anyone have any suggestion on how to determine if an instance of an entity is new or an update to an existing record?

Edit: I forgot to mention, these entities are POCOs built for code-first, so I don't have an EntityState property on the entity itself.

like image 213
KallDrexx Avatar asked Oct 27 '10 02:10

KallDrexx


People also ask

How does EF core detect changes?

By default, EF Core creates a snapshot of every entity's property values when it is first tracked by a DbContext instance. The values stored in this snapshot are then compared against the current values of the entity in order to determine which property values have changed.

How does Entity Framework keep track of changes?

EF Core change tracking works best when the same DbContext instance is used to both query for entities and update them by calling SaveChanges. This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called.

How do I Untrack Entity Framework?

You can just call context. Entry(entity). State = EntityState. Detached and it will stop tracking that particular entity.


2 Answers

Yes, as the above answers state, you check the EntityState for the entity in the OSM.

However, keep in mind this only works for entities attached to the context/graph.

I'm currently working with detached entities (ASP.NET MVC), and because they are not attached to the graph, the EntityState is unchanged.

In this case, i am doing a precautionary call to the DB to grab the entity by the key. If nothing is returned, i do an Add, otherwise i use ApplyCurrentValues to override the values, then do .SaveChanges

I'm still wondering if this is the correct way, but thought i'd put it out there.

I'm using POCO's which have no change tracking, hence i have to do a bit more work.

Since there is no EntityState for the POCO, you have to manually call into the OSM:

var pocosInGraph = ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)

After you Attach/Add, your POCO should be in that collection.

As i said though, if this is for a MVC application, your entities are detached on a HTTP POST, and thus the EntityState will still be unchanged.

In my case, i manually set the EntityState after Attaching:

ctx.Attach(poco);
ctx.ObjectStateManager.ChangeObjectState(poco, EntityState.Modified);
ctx.SaveChanges();
like image 68
RPM1984 Avatar answered Oct 13 '22 01:10

RPM1984


if (x.EntityState == System.Data.EntityState.Added)
//Add
else if (x.EntityState == System.Data.EntityState.Modified)
//Attach

for more info

http://msdn.microsoft.com/en-us/library/system.data.entitystate.aspx

like image 24
franklins Avatar answered Oct 12 '22 23:10

franklins