Entity Framework: Ejecución de Scripts
Si has usado Entity Framwork Code First, sabrás que hay momentos en que necesitamos lanar scripts externos de SQL. Veamos algún ejemplo en concreto.

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.