Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
Solo ef4.3 y versiones posteriores : las características, las API, etc. que se describen en esta página se introdujeron en Entity Framework 4.1. Si usa una versión anterior, no se aplica parte o toda la información.
En este artículo se describe el uso de migraciones de Code First con una base de datos existente, una que no creó Entity Framework.
Nota:
En este artículo se da por supuesto que sabe cómo usar migraciones de Code First en escenarios básicos. Si no lo haces, entonces deberás leer Code First Migrations antes de continuar.
Paso 1: Crear un modelo
El primer paso será crear un modelo de Code First destinado a la base de datos existente. El tema Code First a una base de datos existente proporciona instrucciones detalladas sobre cómo hacerlo.
Nota:
Es importante seguir el resto de los pasos descritos en este tema antes de realizar cambios en el modelo que requerirían cambios en el esquema de la base de datos. Los pasos siguientes requieren que el modelo esté sincronizado con el esquema de la base de datos.
Paso 2: Habilitar migraciones
El siguiente paso es habilitar las migraciones. Para ello, ejecute el comando Enable-Migrations en la consola del Administrador de paquetes.
Este comando creará una carpeta en la solución denominada Migraciones y colocará una sola clase dentro de ella denominada Configuración. La clase Configuration es donde se configuran las migraciones para la aplicación, puede obtener más información sobre ella en el tema Migraciones de Code First .
Paso 3: Agregar una migración inicial
Una vez creadas y aplicadas las migraciones a la base de datos local, es posible que también desee aplicar estos cambios a otras bases de datos. Por ejemplo, la base de datos local puede ser una base de datos de prueba y, en última instancia, también desea aplicar los cambios a una base de datos de producción o a otras bases de datos de prueba de desarrolladores. Hay dos opciones para este paso y la que debe elegir depende de si el esquema de cualquier otra base de datos está vacía o coincide actualmente con el esquema de la base de datos local.
- Opción Uno: use el esquema existente como punto de partida. Debe usar este enfoque cuando otras bases de datos a las que se aplicarán las migraciones en el futuro tendrán el mismo esquema que la base de datos local que tiene actualmente. Por ejemplo, puede usar esto si la base de datos de prueba local coincide actualmente con la versión 1 de la base de datos de producción y posteriormente aplicará estas migraciones para actualizar la base de datos de producción a v2.
- Opción Dos: use la base de datos vacía como punto de partida. Debe usar este enfoque cuando otras bases de datos a las que se aplicarán las migraciones en el futuro están vacías (o aún no existen). Por ejemplo, puede usar esto si ha empezado a desarrollar la aplicación mediante una base de datos de prueba, pero sin usar migraciones y más adelante querrá crear una base de datos de producción desde cero.
Opción Uno: Usar el esquema existente como punto de partida
Las migraciones de Code First usan una instantánea del modelo almacenado en la migración más reciente para detectar cambios en el modelo (puede encontrar información detallada sobre esto en Migraciones de Code First en entornos de equipo). Dado que vamos a suponer que las bases de datos ya tienen el esquema del modelo actual, generaremos una migración vacía (no-op) que tenga el modelo actual como una instantánea.
- Ejecute el comando Add-Migration InitialCreate –IgnoreChanges en la consola del Administrador de paquetes. Esto crea una migración vacía utilizando el modelo actual como un punto de referencia.
- Ejecute el comando Update-Database en la consola del Administrador de paquetes. Esto aplicará la migración InitialCreate a la base de datos. Dado que la migración real no contiene ningún cambio, simplemente agregará una fila a la tabla __MigrationsHistory que indica que esta migración ya se ha aplicado.
Opción Dos: Usar una base de datos vacía como punto de partida
En este escenario, necesitamos migraciones para poder crear toda la base de datos desde cero, incluidas las tablas que ya están presentes en nuestra base de datos local. Vamos a generar una migración InitialCreate que incluya lógica para crear el esquema existente. A continuación, vamos a simular que la base de datos existente ya tiene aplicada esta migración.
- Ejecute el comando Add-Migration InitialCreate en la consola del administrador de paquetes. Esto crea una migración para crear el esquema existente.
- Comenta todo el código del método Up de la migración recién creada. Esto nos permitirá "aplicar" la migración a la base de datos local sin intentar volver a crear todas las tablas, etc. que ya existen.
- Ejecute el comando Update-Database en la consola del Administrador de paquetes. Esto aplicará la migración InitialCreate a la base de datos. Dado que la migración real no contiene ningún cambio (ya que los hemos comentado temporalmente), simplemente agregará una fila a la tabla __MigrationsHistory que indica que esta migración ya se ha aplicado.
- Quite el comentario del código en el método Up. Esto significa que, cuando esta migración se aplica a bases de datos futuras, el esquema que ya existía en la base de datos local se creará mediante migraciones.
Cosas que se deben tener en cuenta
Hay algunas cosas que debe tener en cuenta al usar Migraciones en una base de datos existente.
Es posible que los nombres predeterminados o calculados no coincidan con el esquema existente
Las migraciones especifican explícitamente nombres para columnas y tablas al generar una migración. Sin embargo, hay otros objetos de base de datos para los que Migrations calcula un nombre predeterminado para al aplicar las migraciones. Esto incluye índices y restricciones de clave externa. Al dirigirse a un esquema existente, es posible que estos nombres calculados no coincidan con lo que realmente existe en la base de datos.
Estos son algunos ejemplos de cuándo debe tener en cuenta esto:
Si usó "Option One: Use el esquema existente como punto de partida" del paso 3:
- Si los cambios futuros en el modelo requieren cambiar o quitar uno de los objetos de base de datos cuyo nombre sea diferente, deberá modificar la migración generada automáticamente para especificar el nombre correcto. Las API de Migraciones tienen un parámetro Name opcional que le permite hacerlo. Por ejemplo, el esquema existente puede tener una tabla Post con una columna de clave externa BlogId que tenga un índice denominado IndexFk_BlogId. Sin embargo, de forma predeterminada, las migraciones esperarían que este índice se denominase IX_BlogId. Si realiza un cambio en el modelo que da como resultado la eliminación de este índice, deberá modificar la llamada a DropIndex generada automáticamente para especificar el nombre de IndexFk_BlogId.
Si usó la opción "Option Two: Use empty database as a starting point" (Usar una base de datos vacía como punto de partida) del paso 3:
- Si intenta ejecutar el método Down de la migración inicial (es decir, revertir a una base de datos vacía) en su base de datos local, puede fallar porque las Migraciones intentarán eliminar índices y restricciones de clave externa utilizando nombres incorrectos. Esto solo afectará a la base de datos local, ya que otras bases de datos se crearán desde cero mediante el método Up de la migración inicial. Si desea degradar la base de datos local existente a un estado vacío, es más fácil hacerlo manualmente, ya sea quitando la base de datos o quitando todas las tablas. Después de esta degradación inicial, todos los objetos de la base de datos se recrearán con los nombres por defecto, por lo que este problema no se presentará de nuevo.
- Si los cambios futuros en el modelo requieren cambiar o quitar uno de los objetos de base de datos denominados de forma diferente, esto no funcionará con la base de datos local existente, ya que los nombres no coincidirán con los valores predeterminados. Sin embargo, funcionará con las bases de datos que se crearon "desde cero", ya que usarán los nombres predeterminados elegidos por Migraciones. Puede realizar estos cambios manualmente en la base de datos existente local o considerar la posibilidad de que las migraciones vuelvan a crear la base de datos desde cero, como lo hará en otras máquinas.
- Las bases de datos creadas con el método Up de la migración inicial pueden diferir ligeramente de la base de datos local, ya que se usarán los nombres predeterminados calculados para índices y restricciones de clave externa. También puede terminar con índices adicionales, ya que migraciones crearán índices en columnas de clave externa de forma predeterminada; es posible que esto no haya sido el caso en la base de datos local original.
No todos los objetos de base de datos se representan en el modelo
Migraciones no controlarán los objetos de base de datos que no forman parte del modelo. Esto puede incluir vistas, procedimientos almacenados, permisos, tablas que no forman parte del modelo, índices adicionales, etc.
Estos son algunos ejemplos de cuándo debe tener en cuenta esto:
- Independientemente de la opción elegida en "Paso 3", si los cambios futuros en el modelo requieren cambiar o quitar estos objetos adicionales Migraciones no sabrán realizar estos cambios. Por ejemplo, si quita una columna que tiene un índice adicional, las migraciones no sabrán quitar el índice. Deberá agregarlo manualmente a la migración con scaffolding.
- Si utilizó la opción "Opción Dos: Usar una base de datos vacía como punto de partida", estos objetos adicionales no se crearán a través del método Up de su migración inicial. Puede modificar los métodos Up y Down para gestionar estos objetos adicionales si lo desea. En el caso de los objetos que no se admiten de forma nativa en la API de migraciones , como vistas, puede usar el método Sql para ejecutar SQL sin procesar para crearlos o quitarlos.