Estrategia de inicialización personalizada para el código EF primero que no suelta las tablas para agregar una columna

StackOverflow https://stackoverflow.com/questions/5312017

Pregunta

El último paquete NUGET de Código EF First viene con una implementación personalizada de IDatabaseInitializer llamó DontDropDbJustCreateTablesIfModelChanged. Como su nombre lo indica, cuando se detecta un cambio de modelo, no dejará caer y recreará toda la base de datos, simplemente soltará y recreará las tablas.

Digamos que tengo esta clase de modelo:

public class User
{
    public string Username { get; set; }

    // This property is new; the model has changed!
    public string OpenID { get; set; }
}

¿Cómo se haría para implementar un IDatabaseInitializer que tampoco deja caer ninguna mesa. En este caso, solo agregaría un OpenID columna a la tabla de usuario?

¿Fue útil?

Solución

Creo que es una cuestión de SQL. Entonces, para SQL Server, puede escribir algo como:

public class MyInitializer : IDatabaseInitializer<MyContext>
{
    public void InitializeDatabase(MyContext context)
    {
        context.Database.SqlCommand(
            @"
            IF NOT EXISTS (SELECT 1 FROM sys.columns AS col
                           INNER JOIN sys.tables AS tab ON tab.object_Id = col.object_Id
                           WHERE tab.Name = 'User' AND col.Name = 'OpenId')
            BEGIN
                ALTER TABLE dbo.User ADD OpenId INT; 
            END");
    }
}

Pero de la misma manera, puede ejecutar dicho script sin agregarlo a su aplicación, lo que creo que es un enfoque mucho mejor.

Otros consejos

Con la versión actual del código primero, no puede simplemente modificar su esquema y preservar los datos que pueda tener en sus tablas. Si se mantiene los datos, como las tablas de datos / búsqueda de referencia, es importante con esta versión, puede crear su propio inicializador y anular el método de semilla para llenar sus tablas

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
    protected override void Seed(MyContext context)
    {
        var countries = new List<Country>
        {
            new Country {Id=1, Name="United Kingdom"},
            new Country{Id=2, Name="Ireland"}
        };

        countries.ForEach(c => context.Countries.Add(c));
    }
}

Y luego use esto en su aplicación_start:

Database.SetInitializer<MyContext>(new MyDbInitializer());

Creo que el equipo EF está abordando actualmente, pero no estaba listo para su lanzamiento en el momento en que salió la primera caída del código. Puede ver una vista previa aquí: Código Primeras migraciones

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