Pregunta

He estado usando Entity Framework 4.3 en una base de datos existente y tengo un par de escenarios que estoy tratando de atender.

En primer lugar, si elimino mi base de datos, me gustaría recrear si desde cero, he utilizado con éxito una base de datos creativeAtabaseifnotexists para esto.

En segundo lugar, si actualizo mi modelo y la base de datos ya existe, me gustaría que la base de datos se actualice automáticamente: he utilizado con éxito las migraciones de Entity Framework 4.3 para esto.

Así que aquí está mi pregunta. Digamos que agrego una nueva tabla a mi modelo que requiere algunos datos de referencia, lo que es la mejor manera de garantizar que estos datos se creen tanto cuando la base de datos se ejecuta como cuando se ejecuta la migración. Mi deseo es que los datos se creen cuando estoy creando el DB desde cero y también cuando la base de datos se actualiza como resultado de una migración en ejecución.

En algunos ejemplos de migraciones EF, he visto que las personas usan la función SQL () en el método UP de la migración para crear datos de semillas, pero si es posible, prefiero usar el contexto para crear los datos de semillas (como ve en la mayoría de los ejemplos de iniciales de base de datos) Como me parece extraño que uses SQL puro cuando toda la idea de EF esté abstraer eso. He intentado usar el contexto en el método UP, pero por alguna razón no creía que una tabla creada en la migración existiera cuando intenté agregar los datos de semillas directamente debajo de la llamada para crear la tabla.

Cualquier sabiduría muy apreciada.

¿Fue útil?

Solución

Si desea utilizar entidades en datos de semillas, debe usar Seed Método en su configuración de migraciones. Si genera un proyecto nuevo Enable-Migrations Obtendrá esta clase de configuración:

internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(CFMigrationsWithNoMagic.BlogContext context)
    {
        //  This method will be called after migrating to the latest version.

        //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
        //  to avoid creating duplicate seed data. E.g.
        //
        //    context.People.AddOrUpdate(
        //      p => p.FullName,
        //      new Person { FullName = "Andrew Peters" },
        //      new Person { FullName = "Brice Lambson" },
        //      new Person { FullName = "Rowan Miller" }
        //    );
        //
    }
}

La forma en que las migraciones de los datos de semillas no son muy eficientes porque se supone que debe usarse para una siembra muy básica. Cada actualización de la nueva versión pasará por un conjunto completo e intentará actualizar los datos existentes o insertar nuevos datos. Si no usas AddOrUpdate Método de extensión Debe asegurarse manualmente de que los datos se sembran a la base de datos solo si aún no están presentes.

Si desea una forma eficiente de siembra porque debe sembrar muchos datos, obtendrá un mejor resultado con Common:

public partial class SomeMigration : DbMigration
{
    public override void Up()
    {
        ...
        Sql("UPDATE ...");
        Sql("INSERT ...");
    }

    public override void Down()
    {
        ...
    }
}

Otros consejos

No recomendaría usar Sql() llamadas en tu Up() Método porque (OMI) esto realmente está destinado al código de migración real para el cual no hay una función incorporada, en lugar del código de semillas.

Me gusta pensar en los datos de semillas como algo que podría cambiar en el futuro (incluso si mi esquema no lo hace), por lo que simplemente escribo verificaciones "defensivas" en todas mis inserciones en la función de semilla para asegurarse de que la operación no disparara previamente.

Considere un escenario en el que tenga una tabla de "tipos" que comience con 3 entradas, pero luego agregará un cuarto. No debería necesitar una "migración" para abordar esto.

Usando Seed() También le brinda un contexto completo para trabajar, que es mucho más agradable que usar las cadenas SQL en el Sql() Método que Ladislav demostró.

Además, tenga en cuenta que el beneficio de usar métodos EF incorporados tanto para el código de migración como para el código de semillas es que las operaciones de su base de datos siguen siendo neutrales en la plataforma. Esto significa que sus cambios de esquema y consultas pueden ejecutarse en Oracle, Postgre, etc. Si escribe SQL en bruto real, entonces potencialmente se está bloqueando innecesariamente.

Es posible que esté menos preocupado por esto ya que el 90% de las personas que usan EF solo alcanzarán SQL Server, pero lo estoy lanzando para darle una perspectiva diferente sobre la solución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top