Si trabajáis con Entity Framework Code First, sabréis que los cambios de esquema los realiza bastante bien pero hay momentos en que necesitamos aplicar scripts para migrar datos u otros propósitos.
Veamos como
Lo primero que intentamos siempre es realizar nuestro propio parseador de ficheros para realizar la tarea que queremos. Y así fue :)
Aunque trás algun error y sin poder depurar mucho la migration de pruebas, realizando una búsqueda encontramos una solución muy parecida a la que queriamos. Y trás acceder al código en github y realizar unas modificaciones quedo esto:
public abstract class DbMigrationExtended : DbMigration { public void SqlFile(string fileName, bool suppressTransaction = false) { var cleanAppDir = new Regex(@"\\bin.+"); var dir = AppDomain.CurrentDomain.BaseDirectory; dir = cleanAppDir.Replace(dir, string.Empty); var sqlLines = File.ReadAllLines(Path.Combine(dir, string.Format("Scripts/{0}.sql", fileName))); var ignore = new[] { "GO", // Migrations doesn't support GO "/*", // Migrations might not support comments "--", // Migrations might not support comments "print" // Migrations might not support print }; var sql = string.Join(" ", sqlLines.Where(line => !string.IsNullOrEmpty(line) && !ignore.Any(line.StartsWith))); Sql(sql, suppressTransaction); } }
Adaptaciones Propias
Como podéis ver la complejidad es obtener el directorio de ejecución en el momento de lanzar el update-database desde la consola, además de ignorar ciertas lineas e instrucciones sql por seguridad.
Además hemos realizado una modificación para que por convención nuestros scripts siempre estén ubicadas en una misma carpeta y tengan la misma extensión, en caso contrario fallará; pero nos viene bien para ir cogiendo buenas prácticas de forma que nuestro proyecto tendría esta estructura:
Al final podemos construir una migration lanzando el típico add-migration en la consola y una vez creada heredar de nuestra nueva clase, si es necesario, y agregar la nueva instrucción para invocar ficheros.
Migration de Ejemplo
public partial class SampleMigration : DbMigrationExtended { public override void Up() { SqlFile("MySqlFileNameWithoutExtension"); } public override void Down() { } }
Conclusiones
Si se te ocurre alguna funcionalidad que no provee por defecto .NET, buscalo antes de realizar tu propia funcionalidad, puesto que seguro que antes se le ha ocurrido ya a alguien, hay versiones mejores que la tuya o por lo menos más probadas.