Benutzerdefinierte Initialisierungsstrategie für den EF -Code zuerst, der Tabellen nicht zum Hinzufügen einer Spalte fallen lässt

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

Frage

Das neueste EF -Code First Nuget -Paket enthält eine benutzerdefinierte Implementierung von IDatabaseInitializer genannt DontDropDbJustCreateTablesIfModelChanged. Wie der Name schon sagt, wird die gesamte Datenbank nicht fallen und neu erstellt, wenn eine Modelländerung erkannt wird, einfach fallen und die Tabellen wieder herstellen und neu erstellen.

Sagen Sie, ich habe diese Modellklasse:

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

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

Wie würde man eine implementieren IDatabaseInitializer das lässt auch keine Tische fallen. In diesem Fall würde es nur eine hinzufügen OpenID Spalte zur Benutzertabelle?

War es hilfreich?

Lösung

Ich denke, es ist eine Frage von SQL. Für SQL Server können Sie also so etwas schreiben wie:

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");
    }
}

Auf die gleiche Weise können Sie ein solches Skript ausführen, ohne es Ihrer Anwendung hinzuzufügen, was meiner Meinung nach viel besserer Ansatz ist.

Andere Tipps

Mit der aktuellen Version von Code zuerst können Sie Ihr Schema nicht einfach ändern und Daten in Ihren Tabellen erhalten. Wenn Sie Daten verwalten, z. B. Referenzdaten / Lookup -Tabellen mit dieser Version, können Sie Ihren eigenen Initialisierer erstellen und die Saatgutmethode überschreiben, um Ihre Tabellen zu füllen

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));
    }
}

Und verwenden Sie dies dann in Ihrem application_start:

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

Ich glaube, dass dies derzeit vom EF -Team angesprochen wird, aber nicht bereit für die Veröffentlichung zum Zeitpunkt des ersten Drops. Sie können hier eine Vorschau sehen: Code Erst Migrationen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top