265 Stimmen

Das Modell, das dem <Database>-Kontext zugrunde liegt, hat sich seit der Erstellung der Datenbank geändert

Die Fehlermeldung :

"Das Modell, das dem Kontext 'AddressBook' zugrunde liegt, hat sich seit der Erstellung der Datenbank geändert. Entweder löschen/aktualisieren Sie die Datenbank manuell, oder rufen Sie Database.SetInitializer mit einer IDatabaseInitializer-Instanz auf. Die Strategie RecreateDatabaseIfModelChanges zum Beispiel löscht und erstellt die Datenbank automatisch neu und versorgt sie optional mit neuen Daten."

Ich versuche, die Code-First-Funktion zu verwenden, und habe Folgendes geschrieben:

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

Die Kontextklasse:

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

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

und die Verbindungszeichenfolge:

<?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>

Der Name der Datenbank lautet also "AddressBook", und der Fehler tritt auf, wenn ich versuche, das Kontaktobjekt zum Kontext hinzuzufügen. Habe ich hier etwas übersehen?

18voto

Ashish Gupta Punkte 14526

Ich habe gerade die Antwort herausgefunden und dachte, ich könnte sie hier aktualisieren. Sie müssen nur das Folgende tun.

public class AddressBook: DbContext
{
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
    modelBuilder.IncludeMetadataInDatabase = false;
   }
}

16voto

dwp4ge Punkte 1856

Oder Sie können diese Zeile in Ihre Global.asax.cs-Datei unter Application_Start() einfügen:

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

Stellen Sie sicher, dass Sie ProjectName.Path.Context in Ihren Namespace und Kontext ändern. Wenn Sie zuerst Code verwenden, wird bei jeder Änderung des Schemas eine neue Datenbank erstellt und gelöscht.

8voto

Sergey Kulgan Punkte 1127

Ich habe viele Tage damit verbracht, dieses Problem zu lösen, habe viele verschiedene Beiträge analysiert und viele Optionen ausprobiert und endlich behoben. Diese 2 Projekte in meiner Lösung mit EF-Code erste Migrationen:

  • Konsolenanwendung "DataModel", die hauptsächlich als Assembly, die alle meine Code ersten Entitäten, DbContext, Mirgations und generischen Repository enthält. Ich habe zu diesem Projekt separate leere lokale Datenbankdatei (in DataModel/App_Data-Ordner) enthalten, um Migrationen von Package Manager Console generieren zu können.
  • WebApi, das auf das DataModel-Projekt verweist und eine lokale Datenbankdatei aus dem Ordner WebApi/App_Data verwendet, die nicht im Projekt enthalten ist

Ich erhielt diese Fehlermeldung, als ich WebApi anforderte...

Meine Umgebung:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional mit Update 1
  • alle meine Projekte sind für .NET Framework 4.6.1 bestimmt
  • EntityFramework 6.1.3 von NuGet

Hier habe ich alle Hinweise zusammengestellt, die Sie beachten sollten und alle Bedingungen/Anforderungen, die erfüllt sein müssen, um die genannte Ausnahme zu vermeiden:

  1. Sie sollten nur eine Version des EntityFramework Nuget-Pakets für alle Projekte in Ihrer Lösung verwenden.

  2. Die Datenbank, die durch die sequentielle Ausführung aller Migrationsskripte erstellt wird, sollte dieselbe Struktur bzw. dasselbe Schema wie die Zieldatenbank haben und dem Entitätsmodell entsprechen. Die folgenden 3 Dinge müssen genau übereinstimmen/reflektieren/übereinstimmen:

    • Ihr gesamtes Migrationsskript bis zum letzten
    • Aktueller Code erster Zustand des Entitätsmodells (DbContext, Entitäten)
    • Ziel-Datenbank
  3. Die Zieldatenbank (mdf-Datei) sollte bis zum letzten Migrationsskript aktualisiert werden/entsprechen. Überprüfen Sie, ob die Tabelle "__MigrationHistory" in Ihrer Zieldatenbank Datensätze für alle vorhandenen Migrationsskripte enthält. Das bedeutet, dass alle Migrationsskripte erfolgreich auf diese Datenbank angewendet wurden. Ich empfehle Ihnen, Visual Studio für die Generierung korrekter Code-First-Entitäten und Kontexte zu verwenden, die Ihrer Datenbank entsprechen: Projekt -> Neues Element hinzufügen -> ADO.NET-Entitätsdatenmodell -> Code First aus der Datenbank: Wenn Sie keine Datenbank haben, können Sie natürlich auch manuell ein Modell schreiben (zuerst Entitäten und Kontext codieren) und dann die anfängliche Migration und Datenbank generieren.

  4. Name der Verbindungszeichenfolge z.B. MyConnectionString in der Konfigurationsdatei des Startprojekts (Web.config/App.config):

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

    sollte gleich dem im Konstruktor Ihres DbContext übergebenen Parameter sein:

     public partial class MyDbContext : DbContext
     {
        public MyDbContext()
           : base("name=MyConnectionString"){}
        ...
  5. Vor der Verwendung Paketmanager-Konsole Stellen Sie sicher, dass Sie die richtige Datenbank für die Aktualisierung oder Generierung der Migration verwenden und dass das benötigte Projekt als Startup-Projekt der Lösung. Für die Verbindung zur Datenbank wird die Verbindungszeichenfolge aus der .config-Datei verwendet, die im Projekt als Startprojekt festgelegt ist.

  6. Und der Hauptteil, der mein Problem behoben hat: Es ist seltsam, aber in meinem WebApi/bin-Ordner war DataModel.exe alt und wurde seit dem letzten Build nicht aktualisiert. Da Migrationen in meiner Assembly DataModel.exe eingebettet war, aktualisierte meine WebApi die Datenbank mit alten Migrationen. Ich war verwirrt, warum nach der Aktualisierung der Datenbank in WebApi es nicht mit neuesten Migrationsskript von DataModel entspricht. Folgender Code erstellt automatisch (wenn nicht vorhanden) oder aktualisiert die neueste Migration lokale Datenbank in meinem WebApi/App_Data Ordner.

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

    Ich habe die Lösung "Clean and Rebuild" ausprobiert, aber es hat nicht geholfen, und dann habe ich das Programm komplett entfernt. bin- und obj-Ordner aus WebApi entfernt, Datenbankdateien aus WebApi/App_Data gelöscht, gebaut, WebApi neu gestartet, eine Anfrage gestellt, die korrekte Datenbank erstellt - Lazy Initialization (mit obigen Zeilen), was der letzten Migration entspricht und die Ausnahme erschien nicht mehr. Das könnte Ihr Problem lösen:

    1. Manuelles Entfernen der bin- und obj-Ordner aus Ihrem Startprojekt (die Ihre Datenbank erzeugt/aktualisiert)
    2. bauen Sie Ihr Startup-Projekt oder besser sauber und neu zu bauen alle Sie Lösung.
    3. Erstellen Sie die Datenbank neu, indem Sie das Projekt starten (führt die obigen Zeilen aus) oder verwenden Sie den Befehl "update-database" der Paketmanager-Konsole.
    4. manuell prüfen, ob die generierte db und __MirgationHistory dem letzten Migrationsskript entspricht.

5voto

Robert Koch Punkte 1461

Mit dem Upgrade auf 4.3.1 habe ich die EdmMetaData-Tabelle einfach abgeschnitten oder sie ganz gelöscht.

3voto

Für VB.NET-Entwickler:

Fügen Sie die folgende Zeile in die Datei Glabal.asax.vb am Ende der Methode Application_Start() ein

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

Ändern Sie ApplicationDbContext in Ihren spezifischen Db-Kontext.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X