Model kopii zapasowej kontekstu <Database> zmienił się od czasu utworzenia bazy danych

253

Komunikat o błędzie:

„Model będący podstawą kontekstu„ Książka adresowa ”zmienił się od czasu utworzenia bazy danych. Albo ręcznie usuń / zaktualizuj bazę danych, albo zadzwoń do Database.SetInitializer z instancją IDatabaseInitializer. Na przykład strategia RecreateDatabaseIfModelChanges automatycznie usunie i ponownie utworzy bazę danych, a także opcjonalnie zapisz go nowymi danymi ”.

Próbuję użyć funkcji pierwszego kodu, a oto co napisałem:

var modelBuilder = new ModelBuilder();
var model = modelBuilder.CreateModel();
using (AddressBook context = new AddressBook(model))
{
    var contact = new Contact
    {
        ContactID = 10000,
        FirstName = "Brian",
        LastName = "Lara",
        ModifiedDate = DateTime.Now,
        AddDate = DateTime.Now,
        Title = "Mr."

    };
    context.contacts.Add(contact);
    int result = context.SaveChanges();
    Console.WriteLine("Result :- "+ result.ToString());
}

Klasa kontekstu:

public class AddressBook : DbContext
{
    public AddressBook()
    { }
    public AddressBook(DbModel AddressBook)
        : base(AddressBook)
    {

    }
    public DbSet<Contact> contacts { get; set; }
    public DbSet<Address> Addresses { get; set; }
}

i ciąg połączenia:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
    <add name="AddressBook" providerName="System.Data.SqlClient"  
         connectionString="Data Source=MyMachine;Initial Catalog=AddressBook;
         Integrated Security=True;MultipleActiveResultSets=True;"/>
    </connectionStrings>
</configuration>

Tak więc nazwa bazy danych to „Książka adresowa”, a błąd występuje, gdy próbuję dodać obiekt kontaktu do kontekstu. Czy coś tu brakuje?

Ashish Gupta
źródło
Usuń tabelę __MigrationHistory z bazy danych
Zahid Hasan

Odpowiedzi:

397

Teraz jest:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    Database.SetInitializer<YourDbContext>(null);
    base.OnModelCreating(modelBuilder);
}

w pliku YourDbContext.cs.

Matt Frear
źródło
Zmieniłem ręcznie moją bazę danych produkcji i wyłączyłem migrację i działa, dziękuję
Mohsen Afshin
13
Ps, dzieje się to w Global.asax Application_Start ()
BritishDeveloper
48
Lepsze niż Global.asax jest umieszczenie tego w konstruktorze klasy DbContext. W ten sposób działa dla każdej witryny korzystającej z kontekstu, a nie tylko dla jednej witryny kontrolowanej przez plik Global.asax.
Corin,
7
Prawdopodobnie najlepiej umieścić go w statycznym kontrolerze klasy kontekstowej, więc jest wywoływany tylko raz - jak w tym przykładzie wideo: msdn.microsoft.com/en-us/data/jj572367
Christian Fredh
3
Powinien zostać umieszczony w chronionym zastąpieniu void OnModelCreating (DbModelBuilder modelBuilder) {Database.SetInitializer <YourDbContext> (null); base.OnModelCreating (modelBuilder); }
Chris Voon,
135

Oto kilka informacji z blogu Scotta Gu opublikowanych przez Jeffa na temat tego, co się faktycznie dzieje:

Dla tych, którzy widzą ten wyjątek:

„Model będący podstawą kontekstu„ Produkcja ”zmienił się od czasu utworzenia bazy danych. Można ręcznie usunąć / zaktualizować bazę danych lub wywołać Database.SetInitializerza pomocąIDatabaseInitializer instancji.”

Oto, co się dzieje i co z tym zrobić:

Kiedy model jest tworzony po raz pierwszy, uruchamiamy DatabaseInitializer, aby wykonać takie czynności, jak utworzenie bazy danych, jeśli jej nie ma lub dodanie danych źródłowych. Domyślny DatabaseInitializer próbuje porównać schemat bazy danych potrzebny do użycia modelu z skrótem schematu przechowywanym w tabeli EdmMetadata, która jest tworzona z bazą danych (gdy kodem pierwszym jest ten, który tworzy bazę danych). Istniejące bazy danych nie będą miały tabeli EdmMetadata, a zatem nie będą miały wartości skrótu… a implementacja zostanie dzisiaj rzucona, jeśli ta tabela zostanie pominięta. Będziemy pracować nad zmianą tego zachowania, zanim wyślemy wersję fial, ponieważ jest ona domyślna. Do tego czasu istniejące bazy danych zasadniczo nie wymagają inicjalizacji bazy danych, więc można ją wyłączyć dla danego typu kontekstu, wywołując:

Database.SetInitializer<YourDbContext>(null);

Jeff

Niespokojny
źródło
9
Próbowałem tego dzisiaj i nie otrzymuję już „Model się zmienił”, zamiast tego otrzymuję „Nieprawidłowa nazwa obiektu„ dbo.Table ””
Stefan Bergfeldt
3
Jeff chciał, aby było to obejście, ale minęły już ponad dwa lata, a SetInitializer na wartość zerową jest nadal wymagany. dobrze? Czy ktoś mógłby więc wyjaśnić, jak to pasuje do przepływu pracy migracji?
kroiz
2
@jakejgordon: Ja też z EF6, ale jeśli jest w Global.asax, naprawia problem tylko podczas uruchamiania strony. Jeśli masz testy jednostkowe, jesteś OOL. Lepiej umieścić go w konstruktorze YourDbContext. To naprawia to dla każdego projektu, w tym strony internetowej i projektów testowych.
Rap
1
IMO, odpowiedź ta powinna zostać oceniona wyżej, ponieważ tak naprawdę wyjaśnia, dlaczego musimy dodać ten wiersz kodu. Dziękuję Ci.
Paul
1
@StefanBergfeldt, jeśli ty lub ktokolwiek dostaniesz Invalid object name 'dbo.Tablesprawdzanie ciągu połączenia attachDbFilename i katalog początkowy
benscabbia 12.01.17
41

Dla Entity Framework 5.0.0.0 - 6.1.3

Ty no rzeczywiście chcemy wykonać następujące czynności:

1. using System.Data.Entity;   to startup file (console app --> Program.cs / mvc --> global.asax
2. Database.SetInitializer<YourDatabaseContext>(null);

Tak, Matt Frear ma rację. AKTUALIZACJA -EDYCJA: Zastrzegam , że zgadzam się z innymi, zamiast dodawać ten kod do global.asax dodanego do klasy DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // other code 
    Database.SetInitializer<YOURContext>(null);
    // more code here.
}

Jak wspomnieli inni, jest to również przydatne do przeprowadzania testów jednostkowych.

Obecnie używam tego z Entity Framework 6.1.3 /.net 4.6.1

Wrócę, aby udostępnić fragment CORE w najbliższej przyszłości.

Tom Stickel
źródło
1
Dziękuję Ci! Program.cs zdecydowanie działa na konsole.
HockeyJ
Ale kiedy inicjujesz bazę danych po raz pierwszy, nie tworzy ona bazy danych, jeśli ustawię wartość setinitializer na wartość null w metodzie onModelCreating. Jakieś pomysły ? Eventhoug robię za pomocą (var context = Activator.CreateInstance <TContext> ()) {context.Database.Initialize (true); }
Rupesh Kumar Tiwari
Muszę znaleźć mój kod, którego użyłbym, że czasami komentowałem wiersz i zamieniałem ... Nie przypominam sobie problemu, muszę poszukać.
Tom Stickel,
1
Najlepszym rozwiązaniem. Powoduje to uruchomienie mojego rozwiązania i nie mam pojęcia, jakie są konsekwencje. Zatwierdź i wdróż.
Svend
32

Wystarczy uruchomić następujące polecenie sql w SQL Server Management Studio:

delete FROM [dbo].[__MigrationHistory]
Shafqat Ali
źródło
1
Uratowałeś mi życie! Dziękuję Ci.
Marek Dorda,
31

Ta poprawka nie działa już po CTP5.

Musisz zrobić Database.SetInitializer<YourContext>(null);

chrisortman
źródło
1
Dokąd to idzie ... OnModelCreating nie ma dostępnej nic o nazwie DbDatabase
James Reategui
Gdzieś podczas uruchamiania ustawiam mój w Application_Start.
chrisortman
Database.SetInitializer wydaje się działać dobrze w wersji ostatecznej EF 4.3.
Richard Beier
Zakładam, że „Ta poprawka nie działa już po CTP5” oznacza, że ​​mówi Akceptowana odpowiedź z 30 sierpnia 2010 roku.
Tom Stickel,
19

Właśnie znalazłem odpowiedź i pomyślałem o aktualizacji tutaj. Wystarczy wykonać następujące czynności.

public class AddressBook: DbContext
{
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
    modelBuilder.IncludeMetadataInDatabase = false;
   }
}
Ashish Gupta
źródło
12
Nie jest to już możliwe w przypadku późniejszych wersji EF, również modelBuilder.Conventions.Remove<IncludeMetadataConvention>();nie pomaga w tej sytuacji. DbDatabase.SetInitialzer (null); działa.
JTew
@TomStickel - Zgadzam się. Oznaczony jako stackoverflow.com/a/6143116/255562 .
Ashish Gupta,
16

Lub możesz umieścić tę linię w pliku Global.asax.cs w Application_Start ():

System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ProjectName.Path.Context>());

Pamiętaj, aby zmienić ProjectName.Path.Context do przestrzeni nazw i kontekstu. Jeśli najpierw użyjesz kodu, spowoduje to usunięcie i utworzenie nowej bazy danych za każdym razem, gdy zostaną wprowadzone zmiany w schemacie.

goodies4uall
źródło
Właśnie tego potrzebowałem, ponieważ robiłem tylko prototypowanie. Wielkie dzięki.
Uczeń
8

Spędziłem wiele dni, aby rozwiązać ten problem, przeanalizowałem wiele różnych postów, wypróbowałem wiele opcji i ostatecznie naprawiłem. Te dwa projekty w moim rozwiązaniu przy użyciu pierwszych migracji kodu EF:

  • Aplikacja konsoli „DataModel”, która głównie używa jako zestawu, który zawiera wszystkie moje pierwsze jednostki kodu, DbContext, Mirgations i ogólne repozytorium. Do projektu załączyłem osobny pusty plik lokalnej bazy danych (w folderze DataModel / App_Data), aby móc generować migracje z konsoli Menedżera pakietów.
  • WebApi, która odwołuje się do projektu DataModel i korzysta z lokalnego pliku bazy danych z folderu WebApi / App_Data, który nie został uwzględniony w projekcie

Wystąpił ten błąd na żądanie WebApi ...

Moje środowisko:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional z aktualizacją 1
  • wszystkie moje projekty ukierunkowane na .NET Framework 4.6.1
  • EntityFramework 6.1.3 z NuGet

Tutaj zebrałem wszystkie uwagi, na które należy zwrócić uwagę oraz wszystkie warunki / wymagania, które należy spełnić, aby uniknąć wspomnianego wyjątku:

  1. Powinieneś używać tylko jednej wersji pakietu EntityFramework Nuget dla wszystkich projektów w swoim rozwiązaniu.
  2. Baza danych, utworzona przez sekwencyjne uruchamianie wszystkich skryptów migracji, powinna mieć tę samą strukturę / schemat co docelowa baza danych i odpowiadać modelowi encji. Poniższe 3 rzeczy muszą dokładnie odpowiadać / odzwierciedlać / pasować do siebie:
    • Twój cały skrypt migracji do końca
    • Aktualny stan pierwszego modelu modelu encji (DbContext, encje)
    • Docelowa baza danych
  3. Docelowa baza danych (plik mdf) powinna być aktualizowana / odpowiadać najnowszemu skryptowi migracji. Sprawdź, czy tabela „__MigrationHistory” w docelowej bazie danych zawiera rekordy dla wszystkich posiadanych skryptów migracji, co oznacza, że ​​wszystkie skrypty migracji zostały pomyślnie zastosowane do tej bazy danych. Polecam używać programu Visual Studio do generowania poprawnych kodów pierwszych encji i kontekstu, który odpowiada Twojej bazie danych, Projekt -> Dodaj nowy element -> Model danych encji ADO.NET -> Kod po pierwsze z bazy danych: Oczywiście jako alternatywę, jeśli nie masz bazy danych, możesz ręcznie napisać model (najpierw koduj encje i kontekst), a następnie wygeneruj początkową migrację i bazę danych.
  4. Nazwa ciągu połączenia, np. MyConnectionString w pliku konfiguracyjnym projektu startowego (Web.config / App.config):

    <configuration>
      <connectionStrings>
        <add name="MyConnectionString" connectionString="...">
      </connectionStrings>
    <configuration>

    powinien być równy parametrowi przekazanemu w konstruktorze DbContext:

     public partial class MyDbContext : DbContext
     {
        public MyDbContext()
           : base("name=MyConnectionString"){}
        ...
  5. Przed użyciem konsoli Menedżera pakietów upewnij się, że używasz poprawnej bazy danych do aktualizacji lub wygenerowania migracji, a potrzebny projekt jest ustawiony jako projekt startowy rozwiązania. Do połączenia z bazą danych użyje ciągu połączenia z tego pliku .config, który w projekcie jest ustawiony jako projekt startowy.
  6. I główny, który naprawił mój problem: to dziwne, ale w moim folderze WebApi / bin DataModel.exe był stary, nie odświeżany od ostatniej kompilacji. Ponieważ migracje zostały osadzone w moim zestawie DataModel.exe, moja baza danych WebApi zaktualizowała bazę danych za pomocą starych mirgacji. Byłem zdezorientowany, dlaczego po aktualizacji bazy danych w WebApi nie odpowiada to najnowszemu skryptowi migracji z DataModel. Poniższy kod automatycznie tworzy (jeśli nie istnieje) lub aktualizuje najnowszą lokalną bazę danych migracji w moim folderze WebApi / App_Data.

       public class WebApiApplication : System.Web.HttpApplication
       {
           protected void Application_Start()
           {
               Database.SetInitializer(new MigrateDatabaseToLatestVersion<ODS_DbContext, Configuration>()); 
               ...

    Próbowałem wyczyścić i przebudować rozwiązanie, ale to nie pomogło, ponieważ całkowicie usunąłem foldery bin i obj z WebApi, usunąłem pliki bazy danych z WebApi / App_Data, zbudowałem, zrestartowałem WebApi, wysłałem zapytanie, utworzyłem poprawną bazę danych - leniwa inicjalizacja (przy użyciu linii powyżej), co odpowiada najnowszej migracji, a wyjątek nie pojawiał się więcej. Może to rozwiązać problem:

    1. ręcznie usuń foldery bin, obj z projektu startowego (który generuje / aktualizuje bazę danych)
    2. zbuduj swój projekt startowy lub lepiej wyczyść i przebuduj wszystkie swoje rozwiązania.
    3. utwórz ponownie bazę danych, uruchamiając projekt (wykona wiersze powyżej) lub użyj polecenia „update-database” w konsoli Package Manager Console.
    4. ręcznie sprawdź, czy wygenerowany plik db i __MirgationHistory odpowiada najnowszemu skryptowi migracji.
Sergey Kulgan
źródło
5

Dla mnie, dzięki aktualizacji do 4.3.1, po prostu obcinam tabelę EdmMetaData lub po prostu ją usuwam.

Robert Koch
źródło
Zaktualizowałem do wersji 4.3.1, a następnie zmieniłem nazwę tabeli EdmMaetaData. Mogę teraz wprowadzać zmiany w modelu w razie potrzeby i nie więcej irytujących komunikatów o błędach dotyczących modelu wspierającego bla bla.
Ashok Padmanabhan
3

Dla programistów VB.NET:

Dodaj następujący wiersz do pliku Glabal.asax.vb na końcu metody Application_Start ()

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

Zmień ApplicationDbContext na określony kontekst Db.

Eric Schneider
źródło
2

Miałem ten problem i okazało się, że jeden projekt wskazywał na SQLExpress, ale ten z problemem wskazywał na LocalDb. (w odpowiednim pliku web.config). Głupi nadzór, ale warto tutaj zauważyć, na wypadek, gdyby ktoś rozwiązał ten problem.

stuartdotnet
źródło
2

Oznacza to, że były pewne zmiany w kontekście, które nie zostały wykonane. Najpierw uruchom Add-Migration, aby wygenerować zmiany, które wprowadziliśmy (zmiany, których możemy nie znać), a następnie uruchom Update-Database

Kerisnarendra
źródło
2

Miałem ten sam problem - ponowne dodanie migracji i aktualizacja bazy danych nie działało i żadna z powyższych odpowiedzi nie wydawała się prawidłowa. Wówczas uderzyły mnie inspiracje - używam wielu warstw (jednej sieci, jednej danych i jednej firmy). Warstwa danych ma kontekst i wszystkie modele. Warstwa internetowa nigdy nie zgłosiła tego wyjątku - była to warstwa biznesowa (którą ustawiłem jako aplikację konsolową do testowania i debugowania). Okazuje się, że warstwa biznesowa nie używała prawidłowego ciągu połączenia, aby uzyskać bazę danych i utworzyć kontekst. Dodałem więc ciąg połączenia do konfiguracji aplikacji warstwy biznesowej (i warstwy danych) i viola to działa. Umieszczam to tutaj dla innych osób, które mogą napotkać ten sam problem.

Richard Barker
źródło
1

Korzystam z metody Database.CompatibleWithModel (dostępnej w EF5), aby sprawdzić, czy model i DB są zgodne przed użyciem. Nazywam tę metodę zaraz po utworzeniu kontekstu ...

        // test the context to see if the model is out of sync with the db...
        if (!MyContext.Database.CompatibleWithModel(true))
        {
            // delete the old version of the database...
            if (File.Exists(databaseFileName))
                File.Delete(databaseFileName);
            MyContext.Database.Initialize(true);

            // re-populate database

        }
flobadob
źródło
1

Dobra sugestia nie jest jednak tak dokładna we wszystkich przypadkach. Rozgaduję jeden. Upewnij się, że uruchamiasz „enable-migrations” przy użyciu okien PM w Visual Studio, a folder migracji zostanie dodany do twojego projektu.

Upewnij się, że dwa pliki klasy c # dodane do folderu będą zawierać wszystkie twoje modele i ich odpowiednie właściwości.

Jeśli masz wszystko, co tworzy rozwiązanie i publikuje do wdrożenia.

Logika jest taka, że ​​istniejących metadanych nie można zastąpić, ponieważ aplikacja nie ma metadanych, które mogłyby zastąpić bieżące. W rezultacie pojawia się błąd „Model kopii zapasowej kontekstu zmienił się od czasu utworzenia bazy danych”

Kay Ken
źródło
1

Na wypadek, gdyby ktoś miał taki sam scenariusz jak mój.

Mam bazę danych najpierw EF i jednocześnie używam tożsamości asp.net

więc mam dwa parametry ConnectionStrings w moim webconfig i nie ma z tym problemu. Zdarzyło się, że utworzyłem / uruchomiłem skrypty do ręcznego generowania tabel tożsamości asp.net, których nie powinienem.

więc DROP najpierw wszystkie tabele tożsamości asp.net utworzone przez ciebie ręcznie / ze skryptów.

DROP TABLE __MigrationHistory
DROP TABLE AspNetRoles
DROP TABLE AspNetUserClaims
DROP TABLE AspNetUserLogins
DROP TABLE AspNetUserRoles
DROP TABLE AspNetUsers
Francis Saul
źródło
1

Żadne z tych rozwiązań nie działałoby dla nas (oprócz całkowitego wyłączenia sprawdzania schematu). W końcu mieliśmy niedopasowanie w naszej wersji Newtonsoft.json

Nasza AppConfig nie została poprawnie zaktualizowana:

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
  </dependentAssembly>

Rozwiązaniem było poprawienie wersji zestawu do tej, którą faktycznie wdrażaliśmy

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="10.0.0.0" />
  </dependentAssembly>
AcidPAT
źródło
Mieliśmy podobny problem z wersją Newtonsoft.json, kiedy aktualizowaliśmy wersję, problem został rozwiązany.
Rui Estreito,
0

Po kilku badaniach na ten temat, stwierdziłem, że błąd występuje zasadniczo, jeśli masz instancję db utworzoną wcześniej na lokalnym serwerze SQL Express. Więc ilekroć masz aktualizacje na db i spróbuj zaktualizować db / uruchom jakiś kod na db bez uruchamiania Update Databasepolecenia za pomocą Package Manager Console; po pierwsze, musisz ręcznie usunąć poprzednią bazę danych w naszym lokalnym ekspresowym sql express.

Ponadto to rozwiązanie działa, chyba że masz AutomaticMigrationsEnabled = false;w konfiguracji.

Jeśli pracujesz z systemem kontroli wersji (git, svn itp.), A niektórzy inni programiści aktualizują obiekty db w fazie produkcyjnej, ten błąd pojawia się za każdym razem, gdy aktualizujesz bazę kodu i uruchamiasz aplikację.

Jak wspomniano powyżej, istnieją pewne rozwiązania tego na podstawie kodu. Jest to jednak najbardziej praktyczny w niektórych przypadkach.

Mahmut C.
źródło
0

Czytam również książkę Pro ASP.NET MVC 4 i napotkałem ten sam problem, który miałeś. Dla mnie problem zacząłem po wprowadzeniu zmian zalecanych w rozdziale „Dodawanie walidacji modelu”. Rozwiązałem problem poprzez przeniesienie mojej bazy danych z localdb na pełnoprawny serwer SQL Server 2012. (BTW, wiem, że mam szczęście, że mogłem przejść do pełnej wersji, więc nie nienawidź mnie ;-))) Musi być coś z komunikacją z db, która powoduje problem.

J3Speaks
źródło
Skąd wiesz, że jest to komunikacja z bazą danych, a nie na przykład z jej metadanymi?
flup
2
Przepraszam za późną odpowiedź. Okazuje się, że wcale nie jest to problem z komunikacją! Ponowne odtworzenie bazy danych właśnie zamaskowało problem, ponieważ znów dostałem ten sam problem! __Migrationxxx (nie pamiętam dokładnej nazwy tabeli, ponieważ właśnie ją usunąłem) jest tworzony przez ef. Po prostu usuń go i wszystko powinno być w porządku.
J3Speaks
@ MyJ3 Wszyscy ludzie wyrzucają te wszystkie cholerne linie i linie kodu. To wszystko, czego potrzebowałem! Zasługuje na odpowiedź (scenariusz opcjonalny).
Terrance00,
@ Terrance00 Thanks!
J3Speaks
0

Sprawdź następujące kroki

  1. Database.SetInitializer (null); -> w Global.asax.cs

2)

  1. twoja nazwa klasy kontekstowej powinna pasować do zaznaczenia
Siva
źródło
0

Zmodyfikuj Global.asax.cs, w tym Application_Startwydarzenie za pomocą:

Database.SetInitializer<YourDatabaseContext>(
 new DropCreateDatabaseIfModelChanges<YourDatabaseContext>());
oeddy
źródło
5
Osobiście byłbym trochę bardziej zrozumiały.
Casey
3
NIE NIE NIE, nie chcę używać DropCreateDatabaseIfModelChanges 99% czasu!
Tom Stickel,
0

Ten błąd może wskazywać na problem z łańcuchem połączenia i czy nazwa łańcucha połączenia jest zgodna z deklaracją kontekstu bazy danych.

Miałem ten błąd, ponieważ nazwałem lokalną bazę danych niepoprawnie (głupi błąd), a nazwa ciągu połączenia w pliku web.config „DefaultConnection” nie zgadzała się z MyDbContext, tj.

public MyDbContext(): base("DefaultConnection")
{}


<connectionStrings>
    <add name="DefaultConnection" ...
  </connectionStrings>
DanAbdn
źródło
0

Spróbuj użyć bazy danych SetInitializer, która należy do przy użyciu System.Data.Entity;

W Global.asax

protected void Application_Start()
{
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<yourContext>());
}

Spowoduje to utworzenie nowej bazy danych przy każdej zmianie modelu, ale baza danych byłaby pusta. Aby wypełnić ją atrapami danych, możesz użyć Seeding. Które możesz wdrożyć jako:

Siew ::

protected void Application_Start()
{
    Database.SetInitializer(new AddressBookInitializer());
                ----rest code---
}
public class AddressBookInitializer : DropCreateDatabaseIfModelChanges<AddressBook>
{
    protected override void Seed(AddressBook context)
    {
        context.yourmodel.Add(
        {

        });
        base.Seed(context);
    }

}
SinghMavi
źródło
0

To dziwne, ale wszystkie odpowiedzi tutaj były dla mnie bezużyteczne. Dla mnie działał inicjalizator

MigrateDatabaseToLatestVersion

Oto moje rozwiązanie (wiem, może być o wiele prostsze, ale tak to wykorzystuję):

class MyDbMigrateToLatest : MigrateDatabaseToLatestVersion<MyDbContext, Configuration>
{
}

public class MyDbContext: DbContext
{
    public MyDbContext() : base("DbName")
    {
        SetInitializer();
    }

    public MyDbContext(string connString) : base(connString)
    {
        SetInitializer();
    }

    private static void SetInitializer()
    {
        if (ConfigurationManager.AppSettings["RebuildDatabaseOnStart"] == "true")
            Database.SetInitializer(new MyDbInitializerForTesting());
        else
            Database.SetInitializer(new MyDbMigrateToLatest());
    }
}

public sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(MyDbContext context)
    {
        // Whatever
    }
}

MyDbInitializerForTesting dziedziczy po DropCreateDatabaseAlways, więc w niektórych przypadkach (testowanie) cała baza danych jest odbudowywana. W przeciwnym razie jest migrowany do najnowszej wersji.

Moje źródło: https://msdn.microsoft.com/en-us/data/jj591621.aspx#specific

Tomino
źródło
0

Miałem ten sam problem, gdy korzystaliśmy z jednej bazy danych dla dwóch aplikacji. Ustawienie disableDatabaseInitialization="true"w sekcji typu kontekstu działa dla mnie.

<entityFramework>
<providers>
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
<contexts>
  <context type="PreferencesContext, Preferences" disableDatabaseInitialization="true">
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[PreferencesContext, Preferences], [Migrations.Configuration, Preferences]], EntityFramework" />
  </context>
</contexts>

Zobacz więcej szczegółów https://msdn.microsoft.com/en-us/data/jj556606.aspx

Julia Savinkova
źródło
0

Utwórz niestandardowy inicjator kontekstu:

public class MyDbContextInitializer : MigrateDatabaseToLatestVersion<MyDbContext, Migrations.Configuration>
{
    public override void InitializeDatabase(MyDbContext context)
    {
        bool exists = context.Database.Exists();

        base.InitializeDatabase(context);

        if (!exists)
        {         
            MyDbSeed.Seed(context);
        }
    }       
}

Zauważ, że Migrations.Configuration to klasa generująca za pomocą wiersza polecenia migracji w konsoli Menedżera pakietów. Być może trzeba będzie zmienić wewnętrzny na publiczny modyfikator klasy Migrations.Configuration.

I zarejestruj go ze swojego OmModelCreating:

public partial class MyDbContext : DbContext
{

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(new MyDbContextInitializer());

        //other code for creating model
    }
}
Tomas Kubes
źródło
-1

Tutaj chcę udostępnić inną metodę, która zapobiega błędowi tworzenia kopii zapasowej modelu przy zmianie kontekstu:

1) Otwórz plik DbContext

2) Dodaj przestrzeń nazw za pomocą Microsoft.AspNet.Identity.EntityFramework;

3) public MyDbContext (): base ("name = MyDbContext") {Database.SetInitializer (new DropCreateDatabaseAlways ()); }

Milan Goswami
źródło