usar stored procedimientos procedimiento parametros mapeo mapear funcion framework ejecutar devuelve con columnas almacenados almacenado agregar .net c#-4.0 entity-framework-4.1 ef-code-first sql-server-ce

.net - stored - Código de la entidad de código primero: ¿Cómo actualizar manualmente la base de datos?



mapeo entity framework (5)

Construí una pequeña aplicación de demostración WPF que usa EF-Code First para guardar sus datos en un SQL CE 4.0 DB. Funciona bien, a menos que elimine una propiedad de un objeto modelo. Por ejemplo, si elimino "HosteBy" de esta clase .....

public class Dinner { public int DinnerID { get; set; } public string Title { get; set; } public DateTime EventDate { get; set; } public string Address { get; set; } public string HostedBy { get; set; } public virtual ICollection<RSVP> RSVPs { get; set; } }

... arroja esta excepción:

El modelo que respalda el contexto de ''NerdDinners'' 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.

El error persiste incluso después de eliminar manualmente el campo "HosteBy" de la base de datos. ¿Que me estoy perdiendo aqui? ¿Debo eliminar / truncar el archivo db o hay otra solución?


Consulte la sección de este artículo sobre migraciones de código primero con una base de datos existente
http://msdn.microsoft.com/en-us/data/dn579398

En ocasiones, su proyecto y su base de datos pueden desconectarse. Por lo tanto, es posible que deba volver a sincronizar su esquema en función de su base de datos existente.



1) Para crear una migración basada en el esquema existente:
Agregar-Migración InitialCreate

2) Ejecute Update-Database después de eso para agregar la entrada en la tabla _MigrationsHistory para indicar que la migración se completa hasta el esquema existente.


En el primer escenario en el que cambió el primer modelo de código, antes de ir y modificar la base de datos manualmente, la respuesta es abrir la consola del administrador de paquetes (Nuget) y escribir:

update-database -verbose

Excepto: porque en este caso está eliminando una columna, esto informará que está a punto de eliminar algo, y no eliminará nada sin que usted explícitamente diga que está bien. Entonces escribes:

update-database -f -verbose

Ahora esto eliminará la columna que tenía en su Modelo. -verbose dice que te muestre el SQL que ejecuta. Si tiene miedo de dejar que borre cosas y más bien inspeccionar el SQL antes de que se ejecute, use:

actualización-base de datos -f -script

Eso, en cambio, arrojará el SQL a un script que puede examinar y ejecutará usted mismo.

En el caso en que siguió y borró la columna en la base de datos manualmente, ahora tiene un escenario más complejo en sus manos; la tabla EdmMetadata descrita en la otra respuesta aquí contiene un hash de toda la base de datos que ahora no coincide con la base de datos en sí. Puede ejecutar SQL manual para devolver el DB a la forma en que Entity Framework espera (tal como era antes de que lo modificara manualmente, lo que lo vuelve a alinear con el hash) inspeccionando lo que tenía antes y cómo se ve actualmente su BD.

Si eso no es posible, ahora se encuentra en la parte más fea de Entity Framework Code First. Debe eliminar la tabla hash e invertir la ingeniería de la base de datos en archivos de código.

El nombre de la tabla hash depende de la versión de EF. En EF4 anterior, como usted preguntaba, se llama EdmMetadata. En EF5 más nuevo, se llama __MigrationHistory (en System Tables en su base de datos si está buscando en SQL Server Management Studio). Tendrás que borrarlo.

Las buenas noticias sobre el segundo paso, la ingeniería inversa de la base de datos en código, es que Microsoft ha lanzado una herramienta en beta que hará esto por usted.

Recorrido de ingeniería inversa a DB, y EF Power Tools

Puede omitir muchos de los primeros pasos allí ya que solo están configurando un DB y agregando algunas tonterías para que puedan demostrar lo que necesita hacer: Invertir Ingeniero a db.

Actualizar:

También puede ser factible usar una migración manual para evitar este escenario. Haga una copia de seguridad de la base de datos, luego ejecute:

add-migration WhateverYouWantToCallThis

Las modificaciones de db EF Migrations que deben ejecutarse aparecerán en los comandos C # generados. Ahora le toca a usted jugar con ellos para resolver los problemas con lo que está intentando hacer (por ejemplo, intentar eliminar columnas que ya han sido eliminadas), y poner en su lugar las cosas que necesitará en el futuro (por ejemplo, volver a agregar una tabla que todavía tiene en su modelo pero que borró manualmente en su db).

Una vez que haya agregado esto y ejecute update-database -f , EF Code First solo aceptará con la fe que ha actualizado la base de datos de la manera que necesita y actualizará su hash en función del resultado final. Si realizó los cambios correctos, ahora puede continuar con Migraciones de forma normal. Si esto sigue causando errores, generalmente puede copiar los comandos de la migración manual en algún lugar y eliminarlos, restaurar el archivo db de su copia de seguridad, agregar una migración manual nuevamente e intentar nuevamente. En el peor de los casos, recurre al paso de ingeniería inversa anterior.


Si su base de datos contiene alguna tabla extraña con el nombre EdmMetadata su contexto utiliza un nivel muy básico de control de versiones de la base de datos. Cuando creó la base de datos, almacenó un hash de su modelo en esta tabla y cada vez que construye un modelo para su aplicación (la primera vez que usa el contexto después de reiniciar su aplicación) nuevamente calcula el hash y lo compara con el hash almacenado en esa mesa. Significa que cualquier cambio en su modelo dará como resultado un hash diferente y EF reaccionará con la excepción que usted ve. El cambio manual en la base de datos no lo ayudará porque la tabla contiene aún el anterior.

Las soluciones son:

  • Eliminando este control de versiones. Requiere eliminar IncludeMetadataConvention como se describe aquí .
  • Actualizando el hash Requeriría una ingeniería inversa del algoritmo para el cálculo de hash (por ejemplo, Red Gate .NET Reflector, JetBrains dotPeek, SharpDevelop ILSpy o Telerik JustDecompile) y el cálculo de hash nuevo a partir del modelo compilado (o utilizando el reflejo para leer la propiedad interna de DbCompiledModel.ModelHash con hash calculado) que almacenará en la tabla EdmMetadata .
  • Eliminar manualmente la base de datos y dejar que EF cree una nueva: perderá todos los datos
  • Configurar el inicializador en DropCreateDatabaseIfModelChanges - eliminará automáticamente la base de datos y creará una nueva si cambia el modelo - perderá todos los datos

Tres cosas simples que debes recordar cuando trabajas en Code First

  1. Habilitar migraciones
  2. Add-Migration
  3. Actualizar base de datos

Todo se explica por sí mismo.

Debe ejecutar estos comandos en la consola de Package Manager manualmente. Llego tarde pero espero que ayude