.net - migrations - El modelo que respalda el contexto<Database> ha cambiado desde que se creó la base de datos
entity framework database first español (27)
El mensaje de error:
"El modelo que respalda el contexto de la ''Libreta de direcciones'' ha cambiado desde que se creó la base de datos. O elimine / actualice manualmente la base de datos, o llame a Database.SetInitializer con una instancia de IDatabaseInitializer. Por ejemplo, la estrategia RecreateDatabaseIfModelChanges eliminará y recreará automáticamente la base de datos opcionalmente sembrarlo con nuevos datos ".
Estoy tratando de usar la función de código primero y lo siguiente escribí:
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());
}
La clase de contexto:
public class AddressBook : DbContext
{
public AddressBook()
{ }
public AddressBook(DbModel AddressBook)
: base(AddressBook)
{
}
public DbSet<Contact> contacts { get; set; }
public DbSet<Address> Addresses { get; set; }
}
y la cadena de conexión:
<?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>
Entonces, el nombre de la base de datos es "AddressBook" y el error ocurre cuando intento agregar el objeto de contacto al contexto. ¿Me estoy perdiendo algo aquí?
Acabo de encontrar la respuesta y pensado actualizar aquí. Solo necesito hacer lo siguiente.
public class AddressBook: DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.IncludeMetadataInDatabase = false;
}
}
Ahora es:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<YourDbContext>(null);
base.OnModelCreating(modelBuilder);
}
en su archivo YourDbContext.cs.
Aquí hay información del blog de Scott Gu publicado por Jeff sobre lo que realmente está sucediendo:
Para aquellos que están viendo esta excepción:
"El modelo que respalda el contexto de ''Producción'' ha cambiado desde que se creó la base de datos. O elimine / actualice manualmente la base de datos, o llame a
Database.SetInitializer
con una instancia deIDatabaseInitializer
".Aquí está lo que está pasando y qué hacer al respecto:
Cuando se crea un modelo por primera vez, ejecutamos un DatabaseInitializer para hacer cosas como crear la base de datos si no está allí o agregar datos semilla. El DatabaseInitializer predeterminado intenta comparar el esquema de base de datos necesario para usar el modelo con un hash del esquema almacenado en una tabla EdmMetadata que se crea con una base de datos (cuando Code First es el que crea la base de datos). Las bases de datos existentes no tendrán la tabla EdmMetadata y, por lo tanto, no tendrán el hash ... y la implementación de hoy se lanzará si falta esa tabla. Trabajaremos para cambiar este comportamiento antes de enviar la versión fial, ya que es la predeterminada. Hasta entonces, las bases de datos existentes generalmente no necesitan ningún inicializador de base de datos, por lo que se puede desactivar para su tipo de contexto llamando a:
Database.SetInitializer<YourDbContext>(null);
Jeff
Aquí quiero compartir otro método que evita el error de respaldo del modelo cuando el contexto cambia:
1) Abra su archivo DbContext
2) Agregue el espacio de nombres utilizando Microsoft.AspNet.Identity.EntityFramework;
3) public MyDbContext (): base ("name = MyDbContext") {Database.SetInitializer (new DropCreateDatabaseAlways ()); }
Buena sugerencia, sin embargo, no tan precisa en todos los casos. Me imagino uno. Debe asegurarse de ejecutar "habilitar migraciones" usando las ventanas de PM en Visual Studio, y la carpeta de Migración se agregará a su proyecto.
Asegúrese de que los dos archivos de clase c # agregados a la carpeta contengan todos sus modelos y sus respectivas propiedades.
Si tiene todo lo que compila la solución, y publis para la implementación.
La lógica es que los metadatos existentes no se pueden sobrescribir porque su aplicación no tiene metadatos para reemplazar los actuales. Como resultado, aparece este error "El modelo que respalda el contexto ha cambiado desde que se creó la base de datos"
Crear inicializador de contexto personalizado:
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);
}
}
}
Tenga en cuenta que Migrations.Configuration es una clase que se genera mediante la línea de comandos de migración en la Consola del Administrador de Paquetes. Es posible que deba cambiar el modificador interno a público de la clase Migrations.Configuration.
Y regístrelo desde su OmModelCreating:
public partial class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyDbContext>(new MyDbContextInitializer());
//other code for creating model
}
}
Después de algunas investigaciones sobre este tema, encontré que el error se produce básicamente si tiene una instancia de db creada previamente en su servidor SQL local Express. Entonces, siempre que tenga actualizaciones en db e intente actualizar db / ejecute algo de código en db sin ejecutar el comando Update Database
utilizando la Package Manager Console
; En primer lugar, debe eliminar manualmente la db anterior en nuestro SQL Express local.
Además, esta solución funciona a menos que tenga AutomaticMigrationsEnabled = false;
en su configuración.
Si trabaja con un sistema de control de versiones (git, svn, etc.) Y algunos otros desarrolladores actualizan objetos db en la fase de producción, este error aumenta cada vez que actualiza su base de código y ejecuta la aplicación.
Como se indicó anteriormente, hay algunas soluciones para esto en el código base. Sin embargo, este es el más práctico para algunos casos.
Es raro, pero todas las respuestas aquí fueron inútiles para mí. Para mi trabajó inicializador
MigrateDatabaseToLatestVersion
Aquí está mi solución (lo sé, puede ser mucho más simple, pero así es como la uso):
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 simplemente hereda de DropCreateDatabaseAlways así que en algún caso específico (prueba), se reconstruye la base de datos completa. De lo contrario, se migra a la última versión.
Mi fuente: https://msdn.microsoft.com/en-us/data/jj591621.aspx#specific
Esta solución ya no funciona después de CTP5.
Tienes que hacer Database.SetInitializer<YourContext>(null);
Este error puede indicar un problema con su cadena de conexión y si su nombre de cadena de conexión coincide con la declaración de contexto de la base de datos.
Tuve este error porque nombré la base de datos local de manera incorrecta (error tonto) y el nombre de la cadena de conexión en web.config de "DefaultConnection" no coincide con MyDbContext, es decir,
public MyDbContext(): base("DefaultConnection")
{}
<connectionStrings>
<add name="DefaultConnection" ...
</connectionStrings>
Intente usar Database SetInitializer que pertenece a usar System.Data.Entity;
En global.asax
protected void Application_Start()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<yourContext>());
}
Esto creará una nueva base de datos cada vez que se modifique su modelo. Pero su base de datos estaría vacía. Para rellenarlo con datos ficticios, puede utilizar la siembra. Que puedes implementar como:
Siembra ::
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);
}
}
Modifique Global.asax.cs
, incluido el evento Application_Start
con:
Database.SetInitializer<YourDatabaseContext>(
new DropCreateDatabaseIfModelChanges<YourDatabaseContext>());
Ninguna de estas soluciones funcionaría para nosotros (aparte de deshabilitar la verificación del esquema por completo). Al final tuvimos una falta de coincidencia en nuestra versión de Newtonsoft.json
Nuestro AppConfig no se actualizó correctamente:
<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>
La solución fue corregir la versión de ensamblaje a la que estábamos implementando.
<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>
O puede poner esta línea en su archivo Global.asax.cs bajo Application_Start ():
System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ProjectName.Path.Context>());
Asegúrese de cambiar ProjectName.Path.Context a su espacio de nombres y contexto. Si utiliza el código primero, se eliminará y creará una nueva base de datos cada vez que se realicen cambios en el esquema.
Para Entity Framework 5.0.0.0 - 6.1.3
Usted DE hecho quiere hacer lo siguiente:
1. using System.Data.Entity; to startup file (console app --> Program.cs / mvc --> global.asax
2. Database.SetInitializer<YourDatabaseContext>(null);
Sí, Matt Frear tiene razón. ACTUALIZACIÓN -EDIT: La advertencia es que estoy de acuerdo con otros en que en lugar de agregar este código a global.asax agregado a su clase DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// other code
Database.SetInitializer<YOURContext>(null);
// more code
}
Como han mencionado otros, esto también es bueno para manejar la prueba de la unidad.
Actualmente estoy usando esto con Entity Framework 6.1.3 /.net 4.6.1
Para desarrolladores de VB.NET:
Agregue la siguiente línea al archivo Glabal.asax.vb, al final del método Application_Start ()
Database.SetInitializer(Of ApplicationDbContext)(Nothing)
Cambie ApplicationDbContext a su contexto Db específico.
Para mí, con la actualización a 4.3.1, simplemente trunco la tabla EdmMetaData o simplemente la elimino directamente.
Pasé muchos días resolviendo este problema, analicé muchos mensajes diferentes, probé muchas opciones y finalmente lo solucioné. Este 2 proyectos en mi solución utilizando el código EF primeras migraciones:
- Aplicación de consola "DataModel" que utiliza principalmente como ensamblaje que contiene todas las primeras entidades de mi código, DbContext, Mirgations y repositorio genérico. He incluido en este proyecto un archivo de base de datos local vacío separado (en la carpeta DataModel / App_Data) para poder generar migraciones desde la consola de Package Manager.
- WebApi, que hace referencia al proyecto DataModel y usa el archivo de base de datos local de la carpeta WebApi / App_Data, que no está incluido en el proyecto
Recibí este error cuando solicité WebApi ...
Mi entorno:
- Windows 8.1 x64
- Visual Studio 2015 Professional con la Actualización 1
- todos mis proyectos dirigidos a .NET Framework 4.6.1
- EntityFramework 6.1.3 de NuGet
Aquí reuní todos los comentarios que debe prestar atención y todas las condiciones / requisitos que deben cumplirse para evitar la excepción mencionada:
- Debe usar solo una versión del paquete EntityFramework Nuget para todos los proyectos en su solución.
- La base de datos, creada mediante la ejecución secuencial de todos los scripts de migración, debe tener la misma estructura / esquema que la base de datos de destino y corresponder al modelo de entidad. Las siguientes 3 cosas deben corresponder exactamente / reflejar / coincidir entre sí:
- Todo su script de migración hasta el final
- Código actual Estado de primer modelo de entidad (DbContext, entidades)
- Base de datos de destino
- La base de datos de destino (archivo mdf) debe actualizarse / corresponder hasta el último script de migración. Verifique que la tabla "__MigrationHistory" en su base de datos de destino contenga registros de todos los scripts de migración que tiene, esto significa que todos los scripts de migración se aplicaron con éxito a esa base de datos. Le recomiendo usar Visual Studio para generar primero el código correcto de las entidades y el contexto que corresponde a su base de datos, Proyecto -> Agregar nuevo elemento -> Modelo de datos de entidad ADO.NET -> Código primero de la base de datos: Por supuesto, como alternativa, si no tiene una base de datos, puede escribir el modelo manualmente (codificar primero las entidades y el contexto) y luego generar la migración inicial y la base de datos.
Nombre de la cadena de conexión, por ejemplo, MyConnectionString en el archivo de configuración del proyecto de inicio (Web.config / App.config):
<configuration> <connectionStrings> <add name="MyConnectionString" connectionString="..."> </connectionStrings> <configuration>
debe ser igual al parámetro pasado en el constructor de su DbContext:
public partial class MyDbContext : DbContext { public MyDbContext() : base("name=MyConnectionString"){} ...
- Antes de usar la Consola de Package Manager , asegúrese de que está utilizando la base de datos correcta para actualizar o generar la migración y el proyecto necesario se configura como el proyecto de inicio de la solución. Para conectarse a la base de datos, utilizará la cadena de conexión de ese archivo .config, que en el proyecto, se establece como proyecto de inicio.
Y el principal, que solucionó mi problema: es extraño, pero en mi carpeta WebApi / bin, DataModel.exe era antiguo, no actualizado desde la última compilación. Dado que las migraciones se incrustaron en mi ensamblaje DataModel.exe, mi base de datos WebApi se actualizó con los antiguos registros. Estaba confundido por qué después de actualizar la base de datos en WebApi no corresponde al último script de migración de DataModel. El siguiente código crea automáticamente (si no existe) o se actualiza a la base de datos local de migración más reciente en mi carpeta WebApi / App_Data.
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ODS_DbContext, Configuration>()); ...
Intenté limpiar y reconstruir la solución pero no ayudó, de lo que eliminé completamente las carpetas bin y obj de WebApi, eliminé los archivos de base de datos de WebApi / App_Data, construí, reinicié WebApi, le hice una solicitud, creó la base de datos correcta. líneas arriba), que corresponde a la última migración y la excepción no apareció más. Por lo tanto, esto puede solucionar su problema:
- elimine manualmente las carpetas bin, obj de su proyecto de inicio (que genera / actualiza su base de datos)
- construye tu proyecto de inicio o mejor limpia y reconstruye toda tu solución.
- vuelva a crear la base de datos iniciando el proyecto (ejecutará las líneas anteriores) o use el comando "actualizar-base de datos" de la Consola del administrador de paquetes.
- verifique manualmente si la db generada y __MirgationHistory corresponden al último script de migración.
Por si alguien tiene el mismo escenario que el mío.
Tengo la primera base de datos EF y al mismo tiempo que uso la identidad asp.net
así que tengo dos cadenas de conexión en mi webconfig, y no hay problema con eso. Sucedió que creé / ejecuté los scripts para generar manualmente las tablas de identidad asp.net que no debería.
por lo tanto, DROP primero todas las tablas de identidad asp.net creadas manualmente por usted / desde scripts.
DROP TABLE __MigrationHistory
DROP TABLE AspNetRoles
DROP TABLE AspNetUserClaims
DROP TABLE AspNetUserLogins
DROP TABLE AspNetUserRoles
DROP TABLE AspNetUsers
Revisa los siguientes pasos
- Database.SetInitializer (null); -> en Global.asax.cs
2.
- el nombre de su clase de contexto debe coincidir con chequearlo
Significa que hubo algunos cambios en el contexto que no se han ejecutado. Ejecute Add-Migration primero para generar los cambios que hemos realizado (los cambios que quizás no conozcamos) y luego ejecute Update-Database
Simplemente ejecute el comando followng sql en SQL Server Management Studio:
delete FROM [dbo].[__MigrationHistory]
También estoy leyendo el libro Pro ASP.NET MVC 4 y me encontré con el mismo problema que tenías. Para mí, comencé a tener el problema después de realizar los cambios prescritos en la sección ''Agregar modelo de validación'' del libro. La forma en que resolví el problema es mover mi base de datos de localdb al servidor SQL Server 2012 completo. (Por cierto, sé que tengo la suerte de poder cambiar a la versión completa, así que no me odies .--)) Debe haber algo con la comunicación a la base de datos que está causando el problema.
Tuve el mismo problema cuando usamos una base de datos para dos aplicaciones. La configuración disableDatabaseInitialization="true"
en la sección de tipo de contexto funciona para mí.
<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>
Ver más detalles https://msdn.microsoft.com/en-us/data/jj556606.aspx
Tuve el mismo problema: volver a agregar la migración y actualizar la base de datos no funcionó y ninguna de las respuestas anteriores me pareció correcta. Entonces la inspiración me golpeó: estoy usando múltiples niveles (una web, un dato y un negocio). La capa de datos tiene el contexto y todos los modelos. La capa web nunca lanzó esta excepción: era la capa empresarial (que configuré como aplicación de consola para pruebas y depuración). Resulta que la capa empresarial no estaba usando la cadena de conexión correcta para obtener la db y crear el contexto. Así que agregué la cadena de conexión a la configuración de la aplicación de la capa de negocios (y la capa de datos) y viola funciona. Poner esto aquí para otros que puedan encontrar el mismo problema.
Tuve este problema y resultó que un proyecto apuntaba a SQLExpress pero el que tenía el problema apuntaba a LocalDb. (en su respectivo web.config). Un descuido tonto, pero vale la pena anotarlo aquí en caso de que alguien más esté solucionando este problema.
Uso el método Database.CompatibleWithModel (disponible en EF5) para probar si el modelo y la base de datos coinciden antes de usarlo. Llamo a este método justo después de crear el contexto ...
// 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
}