visual tutorial studio remove mvc migrations how framework foreign first existing español enable create code c# sql-server entity-framework-6 code-first code-first-migrations

c# - tutorial - mvc entity framework español



Probar el código de EF primero y las migraciones: obstáculos (2)

Es cierto que solo puede tener una migración pendiente pendiente a la vez durante el desarrollo . Para entender por qué, debes entender cómo se generan las migraciones. El generador funciona comparando el estado actual de su base de datos (el esquema) con el estado actual de su código de modelo. A continuación, crea efectivamente un "script" (una clase C #) que cambia el esquema de la base de datos para que coincida con el modelo. No querrá tener más de uno de estos pendientes al mismo tiempo o los scripts entrarían en conflicto. Tomemos un ejemplo simple:

Digamos que tengo un Widget clase:

class Widget { public int Id { get; set; } public string Name { get; set; } }

y una tabla correspondiente Widgets en la base de datos:

Widgets ------- Id (int, PK, not null) Name (nvarchar(100), not null)

Ahora decido agregar un nuevo Size propiedad a mi clase.

class Widget { public int Id { get; set; } public string Name { get; set; } public int Size { get; set; } // added }

Cuando creo mi migración, el generador mira mi modelo, lo compara con la base de datos y ve que mi modelo de Widget ahora tiene una propiedad de Size , mientras que la tabla correspondiente no tiene una columna de Size . Entonces, la migración resultante termina pareciéndose a esto:

public partial class AddSizeToWidget : DbMigration { public override void Up() { AddColumn("dbo.Widgets", "Size", c => c.Int()); } public override void Down() { DropColumn("dbo.Widgets", "Size"); } }

Ahora imagine que está permitido crear una segunda migración mientras que la primera está pendiente. Todavía no he ejecutado el comando Update-Database , por lo que el esquema de la base de datos de base sigue siendo el mismo. Ahora decido agregar otra propiedad Color a Widget .

Cuando creo una migración para este cambio, el generador compara mi modelo con el estado actual de la base de datos y ve que he agregado dos columnas. Por lo tanto, crea el script correspondiente:

public partial class AddColorToWidget : DbMigration { public override void Up() { AddColumn("dbo.Widgets", "Size", c => c.Int()); AddColumn("dbo.Widgets", "Color", c => c.Int()); } ... }

Así que ahora tengo dos migraciones pendientes, y ambas intentarán agregar una columna Size a la base de datos cuando finalmente se ejecuten. Claramente, eso no va a funcionar. Por eso, solo se permite abrir una migración pendiente a la vez.

Entonces, el flujo de trabajo general durante el desarrollo es:

  1. Cambia tu modelo
  2. Generar una migración
  3. Actualice la base de datos para establecer una nueva línea base
  4. Repetir

Si comete un error, puede retrotraer la base de datos a una migración anterior utilizando el parámetro –TargetMigration del comando Update-Database , luego eliminar las migraciones –TargetMigration de su proyecto y generar una nueva. (Puede usar esto como una forma de combinar varias migraciones pequeñas en un trozo más grande si realmente lo desea, aunque en la práctica me parece que no vale la pena el esfuerzo).

Update-Database –TargetMigration PreviousMigrationName

Ahora, cuando llega el momento de actualizar una base de datos de producción, no tiene que aplicar manualmente cada migración de una en una. Esa es la belleza de las migraciones: se aplican automáticamente cada vez que ejecuta su código actualizado contra la base de datos. Durante la inicialización, EF examina la base de datos de destino y verifica el nivel de migración (esto se almacena en la tabla especial __MigrationHistory que se creó cuando habilitó las migraciones en la base de datos). Para cualquier migración en su código que aún no se haya aplicado, las ejecuta todas en orden para que usted actualice la base de datos.

Espero que esto ayude a aclarar las cosas.

Siempre he sido un programador orientado a bases de datos, por lo que hasta el día de hoy siempre he utilizado un enfoque de programación basado en bases de datos y me siento muy seguro de T-SQL y SQL Server.

Estoy tratando de entender el enfoque de primer código de Entity Framework 6 y, francamente, estoy luchando.

Tengo una base de datos existente, así que hice un Add New Item > ADO.NET Entity Data Model > Code-First from Database y obtuve un montón de clases de C # que representan mi base de datos existente. Hasta aquí todo bien.

Lo que trato de hacer ahora es explorar cómo manejar las actualizaciones continuas de la base de datos, tanto en el esquema como en los datos de búsqueda "estáticos" (pre-rellenos). Mi primera queja es que las entidades que se diseñaron mediante ingeniería inversa desde la base de datos se configuran con la API Fluent, mientras que a mí me parece más natural crear las nuevas tablas que quiero crear como clase C # con anotaciones de datos. ¿Hay algún problema / problema con "mezclar" esos dos enfoques? ¿O podría indicar el paso de ingeniería inversa para simplemente usar atributos de anotación de datos en lugar de la API Fluent en total?

Mi segunda y más grande queja: estoy tratando de crear migraciones pequeñas y agradables, una para cada conjunto de características que estoy tratando de agregar (por ejemplo, una nueva tabla, un nuevo índice, algunas columnas nuevas, etc.), pero parece que no puedo tener más de una sola migración "pendiente" ... cuando tengo una, y modifico más mis clases modelo, y trato de obtener una segunda migración usando add-migration (name of migration) , Me saludan con:

No se puede generar una migración explícita porque están pendientes las siguientes migraciones explícitas: [201510061539107_CreateTableMdsForecast]. Aplique las migraciones explícitas pendientes antes de intentar generar una nueva migración explícita.

Seriamente ?!?!? No puedo tener más de una sola migración pendiente? Necesito ejecutar update-database después de cada pequeña migración que estoy agregando?

¡Parece un inconveniente bastante GRANDE ! Prefiero crear mis 10, 20 migraciones pequeñas, compactas y fáciles de entender, y luego aplicarlas de una sola vez, ¡no hay forma de hacer esto!?!? Esto es realmente difícil de creer ... ¿hay alguna forma de evitar esto?


¿Hay algún problema / problema con "mezclar" esos dos enfoques?

  1. No, no hay problema para mezclarlos.
  2. Puedes hacer más con una configuración fluida que con anotaciones de datos.
  3. La configuración fluida anula la anotación de datos al construir el script de migración.
  4. Puede usar anotaciones de datos para generar DTO y restricciones de front-end / UI dinámicamente, lo que ahorra una gran cantidad de código.
  5. Fluent API tiene la clase EntityTypeConfiguration que te permite crear dominios (en sentido DDD) de objetos dinámicamente y almacenarlos, lo que acelera el trabajo con DbContext.

No puedo tener más de una sola migración "pendiente"

  1. No es 100% cierto. (Tal vez el 50%, pero esto no es un disparate)
  2. Sí, el DbMigrator compara su modelo "hash" con el modelo de base de datos "hash" cuando genera el Db, por lo que le bloquea antes de realizar su nueva migración pequeña. Pero esta no es una razón para pensar que no se pueden hacer pequeños pasos de migración. Solo realizo pequeños pasos de migración todo el tiempo.
  3. Cuando desarrolla una aplicación y utiliza su base de datos local, aplica las migraciones pequeñas una por una a medida que desarrolla la funcionalidad: gradualmente. Al final, despliega en etapas / producción todas sus pequeñas migraciones en una dll con todas las nuevas funcionalidades, y se aplican una a una.