¿Cómo se vuelve a sincronizar EF con el código sin perder datos cuando Update-database devuelve el siguiente mensaje?
Mensaje de error: System.Data.SqlClient.SqlException (0x80131904): Ya existe un objeto llamado '' en la base de datos.
Originalmente escribí esto como una pregunta de respuesta automática, ya que había luchado con el problema durante algún tiempo, al igual que algunos colegas, pero desafortunadamente, mi respuesta se eliminó y no puedo recuperarla.
Como es una situación que sospecho que puede suceder varias veces mientras las personas intentan "limpiar" las migraciones antiguas, pensé que lo documentaría con instrucciones paso a paso.
Descripción de la situación en la que nos encontramos : No pudimos crear una nueva base de datos local porque el script de inicio estaba incompleto, y no pudimos aplicar actualizaciones a la base de datos de producción porque los scripts de migración crean tablas que ya existen. Y, no queríamos borrar los datos de producción.
Síntoma : no se puede ejecutar Update-Database porque está intentando ejecutar el script de creación y la base de datos ya tiene tablas con el mismo nombre.
Mensaje de error: System.Data.SqlClient.SqlException (0x80131904): Ya existe un objeto llamado '' en la base de datos.
Antecedentes del problema : para entender esto con más detalle, recomiendo ver los dos videos a los que se hace referencia aquí: https://msdn.microsoft.com/en-us/library/dn481501(v=vs.113).aspx
Para resumir, EF entiende dónde está la base de datos actual en comparación con donde está el código basado en una tabla en la base de datos llamada dbo .__ MigrationHistory. Cuando mira las secuencias de comandos de migración, intenta volver a ubicarse donde estaba por última vez con las secuencias de comandos. Si no puede, simplemente intenta aplicarlos en orden. Esto significa que vuelve a la secuencia de comandos de creación inicial y, si observa la primera parte del comando ARRIBA, será la CreeateTable para la tabla en la que se produjo el error.
Solución : Lo que debemos hacer es engañar a EF para que piense que la base de datos actual está actualizada, mientras que "no" se aplican estos comandos CreateTable ya que la base de datos de producción ya existe. Una vez que se establece la base de datos de producción, también debemos poder crear bases de datos locales.
Paso 1: Limpie la base de datos de producción Primero, haga una copia de seguridad de su base de datos de producción. En SSMS, haga clic derecho en la base de datos, seleccione "Tareas> Exportar aplicación de nivel de datos ..." y siga las indicaciones. Abra su base de datos de producción y elimine / suelte la tabla dbo .__ MigrationHistory.
Paso 2: limpieza del entorno local Abra la carpeta de migraciones y elimínela. Supongo que puedes recuperar todo esto de Git si es necesario.
Paso 3: recreación inicial En el Administrador de paquetes, ejecute "Habilitar migraciones" (EF le pedirá que use -ContextTypeName si tiene múltiples contextos). Ejecute "Add-Migration Initial -verbose". Esto creará la secuencia de comandos inicial para crear la base de datos desde cero en función del código actual. Si tuvo alguna operación de inicialización en el Configuration.cs anterior, cópielo.
Paso 4: Truco EF En este punto, si ejecutamos la base de datos de actualización , obtendríamos el error original. Por lo tanto, debemos engañar a EF para que piense que está actualizado, sin ejecutar estos comandos. Por lo tanto, ingrese al método Up en la migración inicial que acaba de crear y coméntelo todo.
Paso 5: Actualizar base de datos Sin ningún código para ejecutar en el proceso Arriba, EF creará la tabla dbo .__ MigrationHistory con la entrada correcta para decir que ejecutó este script correctamente. Ve y échale un vistazo si quieres. Ahora, descomenta ese código y guarda. Puede ejecutar Update-Database nuevamente si desea verificar que EF cree que está actualizado. No ejecutará el paso Arriba con todos los comandos CreateTable porque cree que ya lo ha hecho.
Paso 6: Confirme que EF está ACTUALMENTE actualizado. Si tenía un código que aún no tenía migraciones aplicadas, esto es lo que hice ...
Ejecute "Add-Migration MissingMigrations". Esto creará prácticamente una secuencia de comandos vacía. Debido a que el código ya estaba allí, en realidad existían los comandos correctos para crear estas tablas en el script de migración inicial, así que simplemente corte los comandos CreateTable y drop equivalentes en los métodos Arriba y Abajo.
Ahora, ejecute Update-Database nuevamente y observe cómo ejecuta su nuevo script de migración, creando las tablas adecuadas en la base de datos.
Paso 7: Volver a confirmar y confirmar. Construir, probar, correr. Asegúrese de que todo se está ejecutando y confirme los cambios.
Paso 8: Deje que el resto de su equipo sepa cómo proceder. Cuando la siguiente persona se actualice, EF no sabrá qué golpeó, dado que los scripts que se ejecutaron antes no existen. Pero, suponiendo que las bases de datos locales puedan ser eliminadas y recreadas, todo esto es bueno. Deberán eliminar su base de datos local y agregarla, crearla desde EF nuevamente. Si tuvieran cambios locales y migraciones pendientes, recomendaría que vuelvan a crear su base de datos en el maestro, cambien a su rama de características y vuelvan a crear esos scripts de migración desde cero.