Al usar Entity Framework Core 3.0 y enfrentar un problema extraño en el que EF lanzará una excepción si intento actualizar una entidad con ID = 0, cree que ID = 0 es un valor temporal. El mismo código actualiza la entidad con ID = 1 o superior sin ningún problema.

Excepción:

InvalidOperationException: la propiedad 'Id' en el tipo de entidad 'MyType' tiene un valor temporal al intentar cambiar el estado de la entidad a 'Modificado'. Establezca un valor permanente explícitamente o asegúrese de que la base de datos esté configurada para generar valores para esta propiedad.

La excepción se activa en la siguiente declaración:

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

No quiero volver a sembrar todas mis tablas para comenzar con 1.

¿Es este comportamiento esperado con EF? Debería ser posible guardar entidades con ID = 0.

¿Algún consejo sobre cómo resolver esto?

Gracias.

2
AlexVPerl 30 sep. 2019 a las 19:17

1 respuesta

La mejor respuesta

Tienes que hacer algo con este valor ID cero. Es una bomba de tiempo.

Siempre tendrás que estar en guardia porque definitivamente es un comportamiento esperado. EF tiene lógica interna en función de los valores predeterminados clave. En EF6 podrías hacer esto porque estaba menos refinado. (En esta área).

Déjame mostrarte cómo dejar este valor de ID puede ser contraproducente en el futuro.

Tienes este objeto MyType. Llamémoslo entity para seguir algunas convenciones / hábitos de nomenclatura. Su valor de ID es 0 y no está adjunto al contexto.

Ahora suponga que no usa esta forma bastante redundante de adjuntarlo como modificado, sino la nueva forma EF-core:

context.Update(entity);

Ahora no verá ninguna excepción, pero no, el problema no está solucionado. Ha empeorado. El estado del objeto entity es Added ahora y vas a agregar un nuevo registro a tu tabla. Eso incluso podría pasar desapercibido por un tiempo, lo que se suma al montón de desorden que tienes que limpiar más tarde.

Si su valor ID hubiera sido > 0, el método Update de EF habría concluido que es una entidad existente y su estado debería ser Modified.

Puede puede establecer el estado de entity en Modified si (1) no está adjunto y (2) usa ...

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

Y esa es otra bomba de tiempo. Los cambios de código posteriores eliminan la primera condición (no está adjunta) y el boom.

3
Gert Arnold 30 sep. 2019 a las 17:52