AlexVPerl
AlexVPerl

Reputation: 7996

Entity Framework Update Fails for Entity With ID of 0

Using Entity Framework Core 3.0 and facing an odd issue where EF will throw an exception if I try to update an entity with ID=0, it thinks that ID=0 is a temporary value. Same code updates entity with ID=1 or higher without any problems.

Exception:

InvalidOperationException: The property 'Id' on entity type 'MyType' has a temporary value while attempting to change the entity's state to 'Modified'. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.

Exception is triggered on the following statement:

_context.Attach(MyType).State = EntityState.Modified;

I don't want to reseed all my tables to start with 1.

Is this expected behavior with EF? It should be possible to save entities with ID=0.

Any advice on how to resolve this?

Thanks.

Upvotes: 5

Views: 5444

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109080

You have to do something about this zero ID value. It's a ticking time bomb.

You'll always have to be on your guard because it definitely is expected behaviour. EF has inner logic depending on key default values. In EF6 you could do this because it was less refined. (In this area that is).

Let me show you how leaving this ID value can backfire on you in the future.

You have this MyType object. Let's call it entity to follow some naming conventions/habits. Its ID value is 0 and it's not attached to the context.

Now suppose you don't use this rather redundant way to attach it as modified but the new EF-core way:

context.Update(entity);

Now you won't see any exception, but no, the issue isn't fixed. It's gotten worse. The entity object's state is Added now and you're going to add a new record to your table. That might even go unnoticed for a while, adding to the pile of mess you have to clean up later.

Had its ID value been > 0, EF's Update method would have concluded it's an existing entity and its state should be Modified.

You can set entity's state to Modified if (1) it's not attached and (2) you use...

context.Entry(entity).State = EntityState.Modified;

And that's another time bomb. Later code changes remove the first condition (it's not attached) and boom.

Upvotes: 4

Related Questions