property primary name framework foreign first dataannotations data column code annotation ef-code-first primary-key entity-framework-5 ef-migrations

ef-code-first - primary - navigation property entity framework code first



Código de Entity Framework Primeras migraciones: establecer el valor de clave principal (3)

Tengo una tabla que almacena algunos datos adicionales para algunas filas de una tabla como:

public class QuoteExtra { [Key] public int QuoteId { get; set; } // More fields here }

Me gustaría poder agregar filas a esta tabla donde establezco explícitamente la PK.

Si simplemente lo dejo como antes, establecer un valor y enviar la fila hace que el valor se descarte y se reemplace con el valor generado automáticamente desde la base de datos (y la columna se define como una columna de identidad en el esquema real).

Esta parece ser la solución correcta:

public class QuoteExtra { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int QuoteId { get; set; } // More fields here }

Sin embargo, esto en cambio me da la excepción:

No se puede insertar un valor explícito para la columna de identidad en la tabla ''EnumTest'' cuando IDENTITY_INSERT está desactivado.

Entonces, ¿cómo escribo mi clase para poder establecer el valor de una clave principal en EF?

Editar:

Intenté agregar la siguiente migración basada en código para configurar IDENTITY_INSERT en ON:

public override void Up() { Sql("SET IDENTITY_INSERT QuoteExtra ON"); }

Lo ejecuté y lo intenté de nuevo, pero obtuve la misma excepción que la anterior. Lo que es extraño es que la base de datos refleja esta configuración, y la ejecución de SQL contra ella directamente me permite insertar valores arbitrarios para la clave principal, por lo que parece que Entity Framework está aplicando esta regla y descuidando reconocer que IDENTITY_INSERT no está hecho desactivado. ¿Necesito ponerlo en algún lugar de EF?

Edición 2:

Entendí mal la IDENTITY_INSERT; Asumí que configurarlo una vez lo dejé activado para esa tabla indefinidamente. De hecho, dura tanto como la "Sesión", lo que significa que, por ejemplo, configurarlo en una Migración significa que vive ... siempre y cuando esa Migración se ejecute, y no tenga relación con futuras conexiones como mi posterior .Add () con EF , lo que explica por qué todavía obtuve esa excepción: el DB es realmente la fuente de la excepción, no EF. Dado que IDENTITY_INSERT se limita a, como máximo, una tabla por sesión, es una forma bastante ineficiente de hacerlo: no crear una columna de Identity PK en primer lugar parece ser una mejor ruta.


Es la solución correcta pero solo para una nueva tabla. Si cambia la opción generada en la base de datos para una tabla existente, las migraciones de EF no pueden realizar este cambio y su columna QuoteId todavía está marcada como Identity en la base de datos.


Esta es la forma correcta de crear un PK sin el Autoincremento de Identidad habilitado:

public class QuoteExtra { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int QuoteId { get; set; } // More fields here }

Sin embargo, si agrega DatabaseGenerated (DatabaseGeneratedOption.None)] después de que EF Migrations ya haya creado la tabla, no hace nada a la tabla. Si este es su escenario, debe agregar una migración manual para eliminar la tabla:

add-migration RecreateQuoteExtra

Y en la migración:

public override void Up() { DropTable("QuoteExtra"); }

Luego, las Migraciones automáticas de EF volverán a crear automáticamente la tabla sin la restricción de Identidad, lo que le permitirá establecer el valor de PK en cualquier momento, sin tener que ejecutar ningún comando especial como IDENTITY_INSERT ON.

Suena como una forma menos destructiva de hacerlo con EF7 ("Data Motion"), o podrías escribir muchos sql manuales en la migración para crear tablas temporales y mover datos si quisieras evitar perder los datos existentes. en la mesa.

EDITAR: Dependiendo de su escenario, es posible que EF Migrations no vuelva a crear la tabla: si la clase ya existe y ya se ha agregado a su DbContext, simplemente la eliminará y la dejará así, lo que significa que la migración manual no solo se eliminará sino que también se creará. mesa. No es un gran problema ya que el código de andamiaje que EF Migrations genera para usted a partir de la adición de migración creará estas declaraciones para usted, pero es un poco más de código para verificar si hay problemas.


No pude resolver este problema con sus sugerencias, luego traté de recrear toda la base de datos, pero tampoco funcionó.

Para solucionar este problema, debe eliminar la propiedad identity: true en la primera (!) Creación de la columna (por ejemplo, migración inicial).

Tal vez ayude a alguien ..