2011-03-15 8 views
5

El último paquete First Code First NuGet viene con una implementación personalizada de IDatabaseInitializer llamada DontDropDbJustCreateTablesIfModelChanged. Como su nombre lo indica, cuando se detecta un cambio de modelo, no se cae y se recrea toda la base de datos, simplemente suelte y vuelva a crear las tablas.Estrategia de inicialización personalizada para el código EF Primero que no se quitan tablas para agregar una columna

Decir 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 uno va sobre cómo implementar un IDatabaseInitializer que no cae ninguna tabla o bien. En este caso, solo agregaría una columna OpenID a la tabla de Usuario?

Respuesta

5

Creo que es una cuestión de SQL. Así que 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 que puede ejecutar tales guión sin agregarlo a su aplicación que creo que es mucho mejor enfoque.

+0

Sí, fue más un ataque de curiosidad, ya que todas las implementaciones de IDatabaseInitializer disponibles optaron por un enfoque más "destructivo" :) Gracias –

+0

@Sergi Papaseit: Esto es muy interesante. ¿Lo tomaste más? Una de las cosas que deseo implementar en el código de EF 4.1 primero es la base de datos Migraciones. Creo que lo que presentó Ladislav arriba podría ser realmente útil si fuera elaborado y de alguna manera automatizado. Entonces, si has profundizado en esto, por favor, compártelo con nosotros :) – Kassem

+0

@Kassem - En realidad no lo he hecho. Alguien me hizo una muy buena observación aquí en SO, diciendo que esto, por supuesto, solo está pensado para entornos de desarrollo, así que no debería molestarse en dejar caer el db cada vez ... ¡Pero dígame si lo hace! ;) –

2

Con la versión actual de Code First, no puede simplemente modificar su esquema y conservar los datos que pueda tener en sus tablas. Si los datos de mantenimiento, tales como datos de referencia/tablas de búsqueda es importante con esta versión usted puede crear su propia inicializador y reemplaza el método de semillas para poblar las 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 entonces utilizar esto en su Application_Start:

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

Creo que esto está siendo abordado actualmente por el equipo de EF, pero no estaba listo para su lanzamiento en el momento en que salió el primer código. Puede ver una vista previa aquí: Code First Migrations

Cuestiones relacionadas