2014-09-21 9 views
8

Mam następującą sytuację i nie można ustalić prawidłowej strategii migracji. Pomoc jest doceniana.Pierwsza strategia dotycząca kodu źródłowego jednostki Entity z istniejącą bazą danych

  • Aplikacja tworzy i wykorzystuje bazę danych do przechowywania danych
  • Aplikacja wymaga aktualizacji bazy danych po uruchomieniu jeśli potrzebne
  • wykorzystaniem konsoli Menedżer Nuget nie jest opcją. (Dla celów migracji, lokalnie bez problemu)
  • I Have istniejącej bazy danych w dystrybucji, które nie są EF

Teraz chcę zacząć używać kodu EF pierwsze podejście. Co muszę osiągnąć to:

  1. Jeśli nie ma w bazie, a następnie utworzyć jeden
  2. Jeśli baza danych istnieje użytku pusty migracji (tylko będą gotowe do kolejnych uaktualnień)
  3. powinno się na wniosek rozpocząć

Database nie istnieje ====> Tworzenie EF Initial =====> UPG v1 =====> Upg V2

baza danych istnieje =====> Przejdź początkowe, ale być gotowe do kolejne aktualizacje =====> Upg v1 ======> Upg v2

Dzięki za pomoc

Dodatkowe informacje: Jest to baza danych, która istnieje (tylko przykład):

CREATE DATABASE Test 
GO 

Use Test 
GO 
CREATE SCHEMA [TestSchema] AUTHORIZATION [dbo] 
GO 
CREATE TABLE [TestSchema].[Table1](
    [Id] [uniqueidentifier] NOT NULL, 
    [Column1] [nvarchar](500) NOT NULL, 
    [Column2] [bit] NOT NULL, 
    [Column3] [bit] NOT NULL, 
CONSTRAINT [PK_MonitorGroups] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

Korzystanie z reverse engineering EF stworzył wstępną migracji:

public partial class Initial : DbMigration 
    { 
     public override void Up() 
     { 
      CreateTable(
       "TestSchema.Table1", 
       c => new 
        { 
         Id = c.Guid(nullable: false), 
         Column1 = c.String(nullable: false, maxLength: 500), 
         Column2 = c.Boolean(nullable: false), 
         Column3 = c.Boolean(nullable: false), 
        }) 
       .PrimaryKey(t => t.Id); 
     } 

     public override void Down() 
     { 
      DropTable("TestSchema.Table1"); 
     } 
    } 

jeśli używam kodu dostarczonego przez @spender przeciwko nieistniejącej bazie danych wszystko jest w porządku . Jeśli korzystam z istniejącej bazy danych, działa ona dopóki nie zmienię modelu (następna migracja).

To, co widziałem, to że skrypt aktualizacji zwracany przez migrację zawiera całe tworzenie bazy danych. I nie można go wykonać na już istniejących obiektach.

W rzeczywistości można dodać tabelę migracji do istniejącej bazy danych i dodać dane początkowe, ale nie jestem pewien, czy jest to dobre rozwiązanie.

+0

Więc chcesz pozwolić społeczności na wykonanie pracy nad projektem. –

+1

@Farhad nie, po prostu potrzebuję małej pomocy :) – Adi

+0

To jest w porządku;) –

Odpowiedz

11

Zajęło mi to sporo czasu, więc cieszę się, że mogę się nim podzielić.

Najpierw musisz dokonać inżynierii wstecznej bazy danych. Entity framework power tools może zrobić to za Ciebie. Po zainstalowaniu w projekcie zainstaluj EF za pomocą nuget, kliknij prawym przyciskiem myszy węzeł projektu w eksploratorze rozwiązań, a następnie Entity Framework ->Reverse Engineer Code First. Spowoduje to wygenerowanie całej gamy klas modeli i klas odwzorowania do projektu.

Następnie w opakowaniu konsoli Menedżer

Enable-Migrations 

następnie

Add-Migration Initial 

stworzyć migrację opisujący przejście od pustej dB do bieżącego schematu.

Teraz edytować wygenerowany Configuration.cs klasy konstruktora:

public Configuration() 
    { 

     AutomaticMigrationsEnabled = false; 
     AutomaticMigrationDataLossAllowed = false; 
    } 

Dalej, przy starcie aplikacji, (więc może w global.asax Application_Start jeśli uruchomiony z serwera sieciowego), trzeba wywołać migracje. Ta metoda wykona zadanie:

public static void ApplyDatabaseMigrations() 
    { 
     //Configuration is the class created by Enable-Migrations 
     DbMigrationsConfiguration dbMgConfig = new Configuration() 
     { 
      //DbContext subclass generated by EF power tools 
      ContextType = typeof(MyDbContext) 
     }; 
     using (var databaseContext = new MyDbContext()) 
     { 
      try 
      { 
       var database = databaseContext.Database; 
       var migrationConfiguration = dbMgConfig; 
       migrationConfiguration.TargetDatabase = 
        new DbConnectionInfo(database.Connection.ConnectionString, 
             "System.Data.SqlClient"); 
       var migrator = new DbMigrator(migrationConfiguration); 
       migrator.Update(); 
      } 
      catch (AutomaticDataLossException adle) 
      { 
       dbMgConfig.AutomaticMigrationDataLossAllowed = true; 
       var mg = new DbMigrator(dbMgConfig); 
       var scriptor = new MigratorScriptingDecorator(mg); 
       string script = scriptor.ScriptUpdate(null, null); 
       throw new Exception(adle.Message + " : " + script); 
      } 
     } 
    } 

Teraz możesz dodać więcej migracji jak zwykle. Gdy aplikacja zostanie uruchomiona, jeśli migracje nie zostaną zastosowane, zostaną zastosowane po wywołaniu ApplyDatabaseMigrations.

Teraz masz rację w pierwszym kodzie EF. Myślę, że o to prosiłeś, prawda?

+0

najpierw dziękuję za odpowiedź. - Działa dobrze, gdy nie ma bazy danych - Jeśli w bazie danych modelu nie ma żadnych zmian działa poprawnie (można zainicjować kontekst) - Ale wprowadzenie zmian w modelu nie spowoduje aktualizacji istniejącej bazy danych Będę edytować moje pytanie, aby zapewnić więcej info – Adi

+0

Po zmianie modelu należy ponownie "Add-Migration". Spowoduje to utworzenie nowej migracji, która zostanie zastosowana na początku poprzednich migracji. – spender

+0

Załóżmy, że wszystkie inne sprawy działają z wyjątkiem tego: EF utworzona baza danych z 2 migracjami Początkowe i V1 dotyczą istniejącej bazy danych. Istniejąca baza danych jest identyczna z wersją początkową i wymaga zastosowania tylko wersji V1, ale migracja nie wykrywa tego, ponieważ istniejący element db nie ma tabeli migracji (nie jest utworzony z EF). – Adi

Powiązane problemy