update tutorial net migraciones habilitar framework first español eliminar code automaticas asp entity-framework ef-migrations

tutorial - Migraciones de Entity Framework: incluye la instrucción Go solo en la salida de código



update database entity framework code first (5)

Esto es trabajo para mí:

public class MigrationScriptBuilder : SqlServerMigrationSqlGenerator { public override IEnumerable<MigrationStatement> Generate(IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken) { var statements = base.Generate(migrationOperations, providerManifestToken); statements = statements.SelectMany(s => new[] { s, new MigrationStatement { Sql = "GO" } }).ToList(); return statements; } }

Que (como se ve en otras respuestas) se puede usar (flujo de proceso de migración) con este tipo de método en la Configuración de DbContext:

public Configuration() { SetSqlGenerator("System.Data.SqlClient", new MigrationScriptBuilder()); }

Como parte de la planificación de una migración de Entity Framework, para depurar el movimiento de datos, a menudo usaría el parámetro -Script para generar el script.

Luego podría llevar este script al Analizador de consultas y envolverlo en una transacción para probarlo manualmente.

Me encontré con una situación en la que necesitábamos una instrucción Go para ejecutar el script correctamente. El siguiente código se agregó a la migración para generar un Go en el lugar adecuado.

Sql("GO");

Esto agrega una instrucción GO en la posición correcta cuando se usa -Script. Pero cuando no se usa -Script. Tengo la excepción ...

System.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure ''GO''.

¿Hay una forma segura de agregar un comando Ir a la secuencia de comandos?


He usado:

public class MigrationScriptBuilder : SqlServerMigrationSqlGenerator { #if !DEBUG protected override void Generate(System.Data.Entity.Migrations.Model.SqlOperation sqlOperation) { Statement("GO"); base.Generate(sqlOperation); Statement("GO"); } #endif }

Así que cuando se trata de depuración no se bloquea. Y guión desde el modo de liberación.


Llegué a la misma situación recientemente. Mis migraciones de código EF a menudo introducen una nueva tabla o columna, y luego también pongo migraciones de datos usando Sql (...) en esas migraciones que a veces quieren hacer referencia a la nueva tabla / columna. Como señaló, cuando se ejecuta como una migración de código EF, cada declaración parece emitirse como un lote discreto para la base de datos, y por lo tanto no hay problemas. Sin embargo, para satisfacer las restricciones de implementación de producción, convertimos un conjunto de migraciones de código de un sprint en un solo script (usando -Script) para presentar una única migración de script SQL agregada para el equipo de implementación. Este archivo de script a veces falla, como usted señaló, debido a que intenta procesar un solo lote de T SQL desde una única migración de código donde las declaraciones posteriores intentan referirse a una estructura que solo se definió anteriormente en el lote.

No me gustan particularmente ninguno de los dos enfoques que he tomado por ahora para mitigar esto, pero aquí están:

a. Si en ese momento pienso en ello, divido la migración del código en dos migraciones, de modo que cuando se ejecutan los scripts, se dividen en dos (o más) lotes separados. No me gusta esto porque no hay comentarios durante el desarrollo del Código de Migración de que esto es necesario, y por lo tanto parece propenso a errores.

segundo. Cuando genero los scripts agregados, los ejecuto contra una base de datos cero para probarlos, y termino inyectando manualmente declaraciones "GO" cuando sea necesario en ese script. Este es un proceso molesto para tener que retroceder y hacer, y da como resultado una salida de código que no es un reflejo del 100% de las Migraciones de Código.

No he pasado mucho tiempo investigando el código fuente de Migraciones de Código EF para ver si puedo entender por qué interpreta "GO" como un proceso almacenado, y si hay algo en el código fuente que apunte a una forma de Proporcionar una directiva que evite eso.


Terminé usando dos clases de Configuration diferentes cuando ejecuto las migraciones con y sin el parámetro -Script . En una de mis clases de Configuration envuelvo su MigrationSqlGenerator en una implementación personalizada, que agrega las declaraciones GO .


internal sealed class Configuration : DbMigrationsConfiguration<Context> { public Configuration() { AutomaticMigrationsEnabled = false; const string providerInvariantName = "System.Data.SqlClient"; SetSqlGenerator(providerInvariantName, new BatchingMigrationSqlGenerator(GetSqlGenerator(providerInvariantName))); } protected override void Seed(Context context) { } } internal class BatchingMigrationSqlGenerator : MigrationSqlGenerator { private readonly MigrationSqlGenerator migrationSqlGenerator; public BatchingMigrationSqlGenerator(MigrationSqlGenerator migrationSqlGenerator) { this.migrationSqlGenerator = migrationSqlGenerator; } public override IEnumerable<MigrationStatement> Generate(IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken) { var migrationStatements = migrationSqlGenerator.Generate(migrationOperations, providerManifestToken).ToArray(); foreach (var migrationStatement in migrationStatements) { migrationStatement.BatchTerminator = "GO"; } return migrationStatements; } }