Model wspierający kontekst „ApplicationDbContext” zmienił się od czasu utworzenia bazy danych

85

Przede wszystkim nie widziałem tego błędu nigdzie indziej i myślę, że nie jest to powtórzenie, więc najpierw przeczytaj całą sytuację.

Wszystko działało dobrze, a potem próbowałem zaktualizować jedną z moich klas modelu ( klasa App i aktualizacja są teraz komentowane), które wymienię poniżej; i bum miałem ten brzydki błąd.


Model wspierający kontekst „ApplicationDbContext” zmienił się od czasu utworzenia bazy danych. Rozważ użycie migracji Code First do zaktualizowania bazy danych ( http://go.microsoft.com/fwlink/?LinkId=238269 ). w System.Data.Entity.CreateDatabaseIfNotExists 1.InitializeDatabase(TContext context) at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf1.b__e () w System.Data.Entity.Internal.InternalContext.PerformInitializationAction (akcja akcji) w System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization () w System.Data.Entity. Internal.LazyInternalContext.b__4 (InternalContext c) w System.Data.Entity.Internal.RetryAction 1.PerformAction(TInput input) at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action1) w System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase () w System.Data.Entity.Internal.InternalContext.GetEntitySypeSypeType (TypeType entityType) w System.Data.Entity.Internal.Linq.InternalSet1.Initialize() at System.Data.Entity.Internal.Linq.InternalSet1.Include (ścieżka String) w 1.Include(String path) at System.Data.Entity.QueryableExtensions.Include[T](IQueryableźródle System.Data.Entity.Infrastructure.DbQuery 1, ścieżka String) w System.Data.Entity.QueryableExtensions.Include [T, TProperty] ( 1 source, Expressionścieżka IQueryable 1) w Microsoft.AspNet.Identity. EntityFramework.UserStore 6.GetUserAggregateAsync(Expression1) w Microsoft.AspNet.Identity.EntityFramework.UserStore 6.FindByNameAsync(String userName) at Microsoft.AspNet.Identity.UserManager2.FindByNameAsync (String userName) w Microsoft.AspNet.Identity.UserManager`2.d__12.MoveNext () --- Koniec śledzenia stosu z poprzedniej lokalizacji, w której zgłoszono wyjątek --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (zadanie zadania) w System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (zadanie zadania) w ControlPanel.Web.Controllers.Account.Controller.dove : \ Projects \ FULL \ Control Panel \ ControlPanel.Web \ Controllers \ AccountController.cs: wiersz 56

Na początku pomyślałem, że może to być problem z migracjami, więc całkowicie porzuciłem bazę danych, ponownie włączyłem migracje, dodałem migrację Init i zaktualizowałem bazę danych za pomocą

update-database -force -verbose

Wszystko idzie dobrze bez reklamacji, jednak za każdym razem, gdy próbuję zalogować się do mojej witryny, pojawia się poprzedni błąd. Przeprowadziłem migrację około dziesięć razy, nie mogąc rozwiązać problemu.

Oto moje klasy domeny (modele):

public class App
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int AppId { get; set; }
    //[Required]
    public virtual string FacebookId { get; set; }
    //[Required]
    public virtual string Secret { get; set; }      
    public virtual List<User> Users { get; set; }
    public virtual List<Post> Posts { get; set; }      
    //public virtual ApplicationUser Admin { get; set; }
}

public class Post
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int PostId { get; set; }
    public virtual string Content { get; set; }
    public virtual string Link { get; set; }
    public virtual string Image { get; set; }
    public virtual bool IsSpecial { get; set; }
    //[Required]
    public virtual App App { get; set; }
    //[Required]
    public virtual DateTime? PublishDate { get; set; }
}

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int UserId { get; set; }

    [MaxLength(500)]
    public virtual string FacebookId { get; set; }

    [MaxLength(500)]
    public virtual string Token { get; set; }

    //[Required]
    public virtual App App { get; set; }
}

Oto moje IdentityModels:

public class ApplicationUser : IdentityUser
{
    public virtual List<App> Apps { get; set; }
    public bool? IsPremium { get; set; }
    [DataType(DataType.Date)]
    public DateTime? LastPublishDateTime { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("dCon")
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("Admins");
        modelBuilder.Entity<ApplicationUser>().ToTable("Admins");
        modelBuilder.Entity<IdentityUserRole>().ToTable("AdminRoles");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("Logins");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("Claims");
        modelBuilder.Entity<IdentityRole>().ToTable("Roles");
    }
}
a7madx7
źródło
Czy na pewno nie widziałeś tego problemu gdzie indziej? A co z tym linkiem? stackoverflow.com/questions/3600175/…
AndreCruz
4
Nie, nie są takie same, zapewniam cię, próbowałem rozwiązania dostarczonego tam bez żadnych wyników, ich błąd mówi: albo ręcznie usuń / zaktualizuj bazę danych, podczas gdy mój mówi: Rozważ użycie migracji Code First aby zaktualizować bazę danych
a7madx7

Odpowiedzi:

139

Na wypadek, gdyby ktoś inny natknął się na to, że robił pierwszą implementację bazy danych, tak jak ja.

Zrobiłem zmianę, rozszerzając ApplicationUserklasę, dodając nowe pole do AspNetUserstabeli, a następnie wystąpił ten błąd podczas uruchamiania.

Byłem w stanie rozwiązać ten problem, usuwając rekord utworzony w __MigrationHistorytabeli (był tam tylko jeden rekord). Zakładam, że EF zdecydował, że muszę zaktualizować moją bazę danych za pomocą narzędzia do migracji - ale zrobiłem to już ręcznie.

Josh
źródło
1
Baza danych również pierwsza i to naprawiło. Jedynym zapisem było początkowe utworzenie kodu, które najpierw nastąpiło, ale zmodyfikowałem go po użyciu bazy danych i zmianie tabeli na serwerze MS SQL.
SolidSnake4444
Pracował. Otrzymałem błąd, kiedy dodałem widok rusztowania. Klasa kontekstu danych widoku toApplicationDbContext
Vincent Saelzler,
78

To zadziałało dla mnie - żadne inne zmiany nie są wymagane.

DELETE FROM [dbo].[__MigrationHistory]
Daniel de Zwaan
źródło
1
Dla mnie też zadziałał. Bardzo dziwna poprawka. Myślę, że w historii była zerwana migracja. Spróbuję usunąć wszystkie migracje i ponownie utworzyć pierwszą.
hakan
1
@Dave Voyles, możesz uruchomić ten SQL bezpośrednio w SSMS
Daniel de Zwaan
1
U mnie też się sprawdziło - w jednej bazie danych ta tabela istniała, podczas gdy w innej
Tejas
1
Powyższe odpowiedzi nie mogą mi pomóc, ponieważ moje kody działały poprawnie do ostatniej aktualizacji modelu. Twoja odpowiedź załatwiła sprawę. Pozdrawiam!
Sithu
3
To NIE zadziałało dla mnie i spowodowało, że musiałem usunąć bazę danych, ponownie uruchomić migracje i ponownie dodać dane. STRZEC SIĘ.
adamonstack
35

Ten post rozwiązał mój problem. Chodzi o dodanie następującego wiersza Application_Start()w Global.asax:

Database.SetInitializer<Models.YourDbContext>(null);

Jednak powoduje to odtworzenie bazy danych dla każdej edycji w modelu i możesz stracić dane.

Amin Saqi
źródło
4
Nie chcę, aby moje dane zostały uszkodzone lub utracone.
powiedział Roohullah Allem
Nie jest to najlepsze podejście, Sir. Rozwiązanie, ale nie wiarygodne
Ahsan Aftab
13

Jeśli usuniesz tabelę „[__MigrationHistory]” ze swojej „bazy danych> Tabele systemowe”, to zadziała.

Aniket Sharma
źródło
To działa. Ale po usunięciu [__MigrationHistory] tabeli po prostu zaktualizuj także mmodel EDMX.
DmitryBoyko
12

To był taki dziwny błąd ,, To nie był mój błąd na końcu, to był błąd Microsoftu ,, Zainstalowałem Entity w wersji "pre-release" i to on był odpowiedzialny za ten błąd ,, kiedy zaktualizowałem do stabilnej wypuść to zniknęło, dziękuję wszystkim, wierzcie mi, kiedy zadałem to pytanie, szukałem jego rozwiązania przez tydzień, więc jestem prawie pewien, że ten problem nie występuje nigdzie indziej: wersja pliku entity framework.dll, Problem był 6.0.2, jeśli to pomaga.

a7madx7
źródło
12

Wszyscy odczuwają ból głowy z powodu tego błędu: upewnij się, że wszystkie projekty mają odwołanie do tego samego zestawu Entity Framework.

Krótka historia:

Mój model i moja aplikacja znajdowały się w różnych zespołach. Te zestawy odwoływały się do innej wersji Entity Framework. Wydaje mi się, że obie wersje wygenerowały inny identyfikator dla tego samego modelu. Więc kiedy moja aplikacja uruchomiła identyfikator modelu, nie pasował do jednego z ostatnich migracji w __MigrationHistory. Po zaktualizowaniu wszystkich odniesień do najnowszej wersji EF błąd nigdy się nie pojawił.

Hari
źródło
tak, tak było w moim przypadku, większość projektów była z ef6.1.3, podczas gdy nowo utworzony projekt testowy był w jakiś sposób z ef6.0.
ZZZ
7

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 2 projekty w moim rozwiązaniu przy użyciu migracji najpierw kodu EF:

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

Otrzymałem ten błąd, gdy zażądano WebApi ...

Moje otoczenie:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional z aktualizacją Update 1
  • wszystkie moje projekty skierowane do .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. Należy używać tylko jednej wersji pakietu EntityFramework Nuget dla wszystkich projektów w rozwiązaniu.
  2. Baza danych utworzona przez sekwencyjne uruchamianie wszystkich skryptów migracji powinna mieć taką samą strukturę / schemat, jak docelowa baza danych i odpowiadać modelowi jednostki. Następujące 3 rzeczy muszą dokładnie odpowiadać / odzwierciedlać / pasować do siebie:
    • Twój cały skrypt migracji do końca
    • Bieżący kod stanu modelu pierwszej jednostki (DbContext, jednostki)
    • Docelowa baza danych
  3. Docelowa baza danych (plik mdf) powinna zostać zaktualizowana / zgodna z ostatnim skryptem migracji. Sprawdź, czy tabela „__MigrationHistory” w Twojej 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życie Visual Studio do generowania poprawnego kodu w pierwszej kolejności i kontekstu, który odpowiada Twojej bazie danych, Projekt -> Dodaj nowy element -> ADO.NET Entity Data Model -> Code First z bazy danych: Oczywiście alternatywnie, jeśli nie masz bazy danych, możesz napisać ręcznie model (najpierw kod jednostki i kontekst), a następnie wygenerować 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 Twojego 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 generowania migracji, a potrzebny projekt jest ustawiony jako projekt startowy rozwiązania. Do połączenia z bazą danych użyje parametrów połączenia z tego pliku konfiguracyjnego, który w projekcie jest ustawiony jako projekt startowy.
  6. I główny, który rozwiązał mój problem: To dziwne, ale w moim folderze WebApi / bin DataModel.exe był stary, nie odświeżony od ostatniej kompilacji. Ponieważ migracje zostały osadzone w moim zestawie DataModel.exe, moja zaktualizowana baza danych WebApi przy użyciu starych kopii lustrzanych. Byłem zdezorientowany, dlaczego po aktualizacji bazy danych w WebApi nie odpowiada ona najnowszemu skryptowi migracyjnemu 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 nie pomogło, całkowicie usunąłem foldery bin i obj z WebApi, usunąłem pliki bazy danych z WebApi / App_Data, zbudowałem, zrestartowałem WebApi, poprosiłem o to, utworzyłem poprawną bazę danych - leniwa inicjalizacja (używając linie powyżej), który odpowiada najnowszej migracji i wyjątek nie pojawił się więcej. To może rozwiązać Twój problem:

    1. usuń ręcznie bin, obj foldery z projektu startowego (który generuje / aktualizuje bazę danych)
    2. zbuduj swój projekt startowy lub lepiej wyczyść i przebuduj całe swoje rozwiązanie.
    3. ponownie utwórz bazę danych, uruchamiając projekt (spowoduje wykonanie powyższych wierszy) lub użyj polecenia „update-database” konsoli Menedżera pakietów.
    4. ręcznie sprawdź, czy wygenerowana baza danych i __MirgationHistory odpowiadają najnowszemu skryptowi migracji.
Sergey Kulgan
źródło
3

Może się to zdarzyć, gdy zmienisz adnotację danych właściwości modelu. na przykład: dodanie [Wymagane] do właściwości spowoduje oczekującą zmianę w projekcie bazy danych.

Najbezpieczniejszym rozwiązaniem jest uruchomienie na konsoli menedżera pakietów:

add-migration myMirgrationName

który wyświetli dokładne zmiany w metodzie Up (). Dlatego możesz zdecydować, czy naprawdę chcesz zastosować takie zmiany, korzystając z:

update-database

W przeciwnym razie możesz po prostu usunąć najnowszą migrację z tabeli __MigrationHistory i z folderu migracji w Eksploratorze rozwiązań.

Mohamed Nagieb
źródło
To zdecydowanie najlepsza odpowiedź, jaką tutaj widziałem. Sugestia usunięcia historii migracji to moim zdaniem bardzo zły pomysł!
mgrenier
Dzięki za komentarz. Zwykle też nie polecam usuwania historii migracji, ale w szczególnym przypadku poprzedni punkt migracji nie różnił się zbytnio - tj. OP nie wprowadził zbyt wielu modyfikacji modelu - więc pomyślałem, że może jeden krok wstecz może pomóc , usuwając tylko ostatnie rekordy migracji.
Mohamed Nagieb
2

Miałem ten sam problem co a7madx7, ale ze stabilną wersją EF (v6.1.1) i znalazłem rozwiązanie zamieszczone w:

http://cybarlab.com/context-has-changed-since-the-database-was-created

z odmianami: http://patrickdesjardins.com/blog/the-model-backing-the-context-has-changed-since-the-database-was-created-ef4-3

Drugie łącze zawiera konkretną wzmiankę o VB ..... "możesz po prostu dodać cały kontekst bazy danych, który ma ten problem do metody app_start, w pliku global.asax w następujący sposób" :

Database.SetInitializer(Of DatabaseContext)(Nothing)

Uwaga: musiałem zamienić „DatabaseContext” na nazwę mojej klasy implementującej DbContext

Aktualizacja: Ponadto podczas korzystania z podejścia codefirst do łączenia się z istniejącymi tabelami sprawdź bazę danych, aby zobaczyć, czy EF utworzył tabelę „_migrationhistory” do przechowywania mapowań. Zmieniłem nazwę tej tabeli, a następnie mogłem usunąć SetInitializer z global.asax.

user3085342
źródło
2

Po prostu usuń historię migracji w _MigrationHistory w swojej bazie danych. U mnie to zadziałało

k.demas
źródło
1

Właśnie rozwiązałem podobny problem, usuwając wszystkie pliki w folderze witryny, a następnie ponownie go opublikowałem.

Daniel Björk
źródło
1

usuń tożsamość wszystkich tabel

Delete _MigrationHistory
Delete AspNetRoles
Delete AspNetUserClaims
Delete AspNetUserLogins
Delete AspNetRoles
Delete AspNetUser
Majid joghataey
źródło
1

W menu Narzędzia kliknij pozycję Menedżer pakietów NuGet, a następnie kliknij Konsola Menedżera pakietów (PMC). Wprowadź następujące polecenia w PMC.

Enable-Migrations Add-Migration Init Update-Database Uruchom aplikację. Rozwiązanie problemu jest stąd

Sułtan
źródło
1

Kiedy programuję, wolę używać tej praktycznej klasy do konfigurowania migracji.

Mam nadzieję, że to pomoże.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        Database.SetInitializer(new StackOverflowInitializer());
    }

    public class StackOverflowInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
    {
        public StackOverflowInitializer()
        {
            // TODO NOTHING, COMMENT ALL

            // IF CHANGES, RECREATE
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ApplicationDbContext>());

            // CREATE ONLY NOT EXITS
            //Database.SetInitializer<Context>(new CreateDatabaseIfNotExists<ApplicationDbContext>());
        }

    }

    public System.Data.Entity.DbSet<stackoverflow.Models.Company> Companies { get; set; }

}
Andre Mesquita
źródło
0

Usunięcie wierszy w tabeli [__MigrationHistory] ze starszą wersją produktu zadziałało. Ta odpowiedź jest dla tych, którzy nie chcą usuwać całej tabeli [__MigrationHistory]. Po prostu usuń wiersze ze starszą wersją w kolumnie ProductVersion. Mam nadzieję, że to komuś pomoże!

Rajon Tanducar
źródło
0

Poniżej przedstawiono podobny rodzaj błędu, który napotkałem

Model wspierający kontekst „PsnlContext” zmienił się od czasu utworzenia bazy danych. Rozważ użycie migracji Code First do zaktualizowania bazy danych ( http://go.microsoft.com/fwlink/?LinkId=238269 ).

Dodałem poniższą sekcję w zdarzeniu Application Start w Global.asax, aby rozwiązać błąd

Database.SetInitializer (null);

To rozwiązało problem

Lati
źródło
0

po prostu błąd oznacza, że ​​twoje modele mają zmiany i nie są zsynchronizowane z bazą danych, więc przejdź do konsoli menedżera pakietów, add-migration foo2 to da wskazówkę, co powoduje problem, może usunąłeś coś lub w moim przypadku usunąłem adnotację danych . stamtąd możesz uzyskać zmianę i miejmy nadzieję odwrócić ją w swoim modelu.

po tym usuń foo2.

Yusufm.Salh
źródło
0

Wiem, że jestem bardzo spóźniony, ale też chcę wnieść wkład. Ten błąd jest naprawdę dziwny, ponieważ przeglądarka nie jest w stanie zrozumieć, w jaki sposób zmiany powinny być renderowane, ponieważ klasy i ich właściwości mogły ulec zmianie, ale nie zostały zapisane w bazie danych.

Więc zrób jedną rzecz,

utwórz jedną migrację w konsoli Menedżera pakietów (Narzędzia> Menedżer pakietów NuGet> Konsola Menedżera pakietów) za pomocą tego polecenia:

add -igration UpdateMigration

gdzie UpdateMigration to nazwa Twojej migracji. Możesz nadać mu dowolną nazwę, ale podaj konkretną.

Następnie musimy tylko zaktualizować bazę danych, więc uruchom to:

zaktualizować bazę danych

Po zatwierdzeniu zmian w bazie danych wystarczy odświeżyć przeglądarkę i gotowe!

Mam nadzieję że to pomoże.

noobprogrammer
źródło
0

dzieje się tak, ponieważ dodajesz jakąś właściwość do jednego ze swoich modeli, a tego nie robisz update-Database. aby rozwiązać ten problem, musisz usunąć go z modelu lub musisz add-migration anyProperName z tymi właściwościami i Update-database.

HeshanHH
źródło
0

Ten błąd wystąpił, gdy wprowadziłem zmiany w moim modelu i nie wykonałem migracji w celu zaktualizowania bazy danych.

Jeśli kiedykolwiek wprowadzono zmiany w modelu w schemacie migracji Code First

Nie zapomnij dodać migracji

add-migration UpdatesToModelProperites 

Powyższe polecenie odczyta wszystkie zmiany, które wprowadziłeś w modelu i zapisze je w metodach Up () i Down ().

Następnie po prostu zaktualizuj swoją bazę danych za pomocą poniższego polecenia.

update-database

To, co mi pomogło.

Raheel Khan
źródło
-2

Usuń istniejącą bazę danych, utwórz nową bazę danych o tej samej nazwie, skopiuj wszystkie dane ... to zadziała

fałszywe
źródło