c# - correspondiente - Entity Framework 4.1 El modelo que respalda el contexto ha cambiado desde que se creó la base de datos, inmediatamente después de crear DB
el modelo correspondiente al contexto ha cambiado desde que se creó la base de datos (7)
Estoy trabajando en un proyecto que utiliza Entity Framework 4.1 para persistir nuestros diversos objetos en la base de datos (primero el código).
Estoy probando en Visual Studio con un DB de SQL Express local, y nuestro servidor de Jenkins implementa un código comprometido en un servidor de prueba. Cuando esto sucede, cambio temporalmente mi cadena de conexión local para apuntar al servidor de prueba de DB y ejecutar una prueba de unidad para volver a crear la base de datos de prueba para que coincida con nuestras últimas entidades, etc.
Recientemente noté que nuestro servidor de prueba está dando este error:
El modelo que respalda el contexto ''EntityFrameworkUnitOfWork'' ha cambiado desde que se creó la base de datos. Elimine / actualice manualmente la base de datos o llame a Database.SetInitializer con una instancia de IDatabaseInitializer. Por ejemplo, la estrategia DropCreateDatabaseIfModelChanges eliminará automáticamente y volverá a crear la base de datos y, opcionalmente, la inicializará con nuevos datos.
Esto generalmente es una indicación de que nuestro código ha cambiado y necesito ejecutar la prueba unitaria para volver a crear la base de datos. ¡Excepto que acabo de hacer eso! No creo que haya nada de malo en nuestro proceso de implementación: las DLL en el servidor de prueba parecen ser las mismas versiones que en mi entorno local. ¿Hay alguna otra configuración o factores de entorno que puedan causar este error sobre el cambio del modelo desde que se creó la base de datos?
Soy nuevo aquí, ¡gracias por cualquier ayuda!
El código de Entity Framework primero crea una tabla llamada EdmMetadata. Mantiene un hash de tu modelo actual. Una vez que ejecuta la aplicación, EF comprueba si el modelo que se utiliza es el mismo que el modelo sobre el que ''conoce'' la base de datos.
Si desea realizar una migración de la base de datos, le sugiero que utilice las primeras migraciones del Código EF aunque siga siendo un alfa.
Si no desea usar migraciones, puede:
manejar el cambio de esquema manualmente - eso significa mover el contenido de la tabla EdmMetadata al servidor de prueba junto con todos los cambios
o
configure el inicializador db en DropCreateDatabaseIfModelChanges (o mejor algo derivado de él y use el método Seed () para escribir los datos iniciales). Para configurar el inicializador, llame a Database.SetInitializer () al inicio de la aplicación o use appSettings
<add key="DatabaseInitializerForType Fully.Qualified.Name.Of.Your.DbContext," value="Fully.Qualified.Name.Of.The.Initializer" />
Esto puede suceder debido a diferencias de ordenación de reflexión en diferentes plataformas. Para verificar, puede usar la API de EdmxWriter para comparar el EDMX de ambos entornos. Si alguna de las tablas tiene un orden de columnas diferente, este es el problema.
Para solucionarlo, puede cambiar la forma en que su base de datos de prueba se actualiza de modo que se actualice desde su servidor de prueba en lugar de su casilla local.
Vamos a solucionar este problema en la próxima versión.
¿Los dos servidores que ejecutan su aplicación ejecutan diferentes sistemas operativos (o paquetes de servicio?). Parece que el SHA256CryptoService utilizado puede arrojar una excepción PlatformNotSupportedException que hace que se repliegue a otro método.
// System.Data.Entity.Internal.CodeFirstCachedMetadataWorkspace
private static SHA256 GetSha256HashAlgorithm()
{
SHA256 result;
try
{
result = new SHA256CryptoServiceProvider();
}
catch (PlatformNotSupportedException)
{
result = new SHA256Managed();
}
return result;
}
Puede probar esto utilizando el reflejo para invocar los siguientes 2 métodos (internos / privados) en cada servidor.
MetaDataWorkspace.ToMetadataWorkspace(DbDatabaseMapping, Action<string>)
CodeFirstCachedMetadataWorkspace.ComputeSha256Hash(string xml);
Solo accidentalmente renombré mi archivo .mdf y obtuve este error. Así que busca también esto.
En el enfoque de primer código, el SSDL se genera durante la ejecución del código. Una de las informaciones incluidas en el SSDL generado es el nombre del proveedor utilizado en DbConnection. Como dijo, se está conectando a diferentes motores de bases de datos, por lo que debe usar dos proveedores diferentes. Esto cambia completamente la salida de la función hashing.
El código siguiente se extrajo del ensamblado EntityFramework:
using (XmlWriter writer = XmlWriter.Create(output, settings))
{
new SsdlSerializer().Serialize(database, providerInfo.ProviderInvariantName, providerInfo.ProviderManifestToken, writer);
}
El error que ve significa que el hash del modelo almacenado en la tabla EdmMetadata
es diferente del hash del modelo calculado a partir del modelo en la aplicación. Debido a que está ejecutando la creación de la base de datos desde una aplicación diferente (su aplicación de desarrollo), es posible que esos dos difieran. Un consejo simple aquí es: no utilice diferentes aplicaciones para la creación de bases de datos y, en su lugar, permita que su aplicación principal cree la base de datos (ya sea automáticamente o, por ejemplo, con alguna interfaz de administración).
Como otra opción, debería poder desactivar completamente este cheque eliminando la convención responsable de estos controles:
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
El cómputo de hash de modelo depende de las entidades actuales en su aplicación (cualquier resultado de cambio simple en hash de modelo diferente) y en versiones / manifiesto de servidor de base de datos. Por ejemplo, un modelo implementado en SQL Server 2005 y 2008 tendrá un hash de modelo diferente (Express vs. Full o 2008 vs. 2008 R2 no debería dar como resultado un hash de modelo diferente).
Esto podría ayudar y el enlace al blog de Scott G será seguramente una solución a su problema .
Editar 1: este es el enlace al blog de Scott G
Edición 2: también puede verificar esto si usa una base de datos primero en el servidor de integración
Editar 3: esta es una respuesta más detallada como la de Scott G