Propagación de datos

La inicialización de datos es el proceso de rellenar una base de datos con un conjunto inicial de datos.

Hay varias maneras de hacerlo en EF Core:

  • Datos de ed. de modelo
  • Personalización de la migración manual
  • Lógica de inicialización personalizada

Datos de ed. de modelo

A diferencia de EF6, en EF Core, los datos de edación se pueden asociar a un tipo de entidad como parte de la configuración del modelo. A EF Core las migraciones pueden calcular automáticamente qué operaciones de inserción, actualización o eliminación deben aplicarse al actualizar la base de datos a una nueva versión del modelo.

Nota

Las migraciones solo tienen en cuenta los cambios del modelo al determinar qué operación se debe realizar para que los datos de valor de ed se obtengan en el estado deseado. Por lo tanto, cualquier cambio en los datos realizados fuera de las migraciones podría perderse o provocar un error.

Por ejemplo, esto configurará los datos de ed para en BlogOnModelCreating :

modelBuilder.Entity<Blog>().HasData(new Blog { BlogId = 1, Url = "http://sample.com" });

Para agregar entidades que tienen una relación, es necesario especificar los valores de clave externa:

modelBuilder.Entity<Post>().HasData(
    new Post { BlogId = 1, PostId = 1, Title = "First post", Content = "Test 1" });

Si el tipo de entidad tiene alguna propiedad en estado de sombra, se puede usar una clase anónima para proporcionar los valores:

modelBuilder.Entity<Post>().HasData(
    new { BlogId = 1, PostId = 2, Title = "Second post", Content = "Test 2" });

Los tipos de entidad de propiedad se pueden seeder de forma similar:

modelBuilder.Entity<Post>().OwnsOne(p => p.AuthorName).HasData(
    new { PostId = 1, First = "Andriy", Last = "Svyryd" },
    new { PostId = 2, First = "Diego", Last = "Vega" });

Consulte el proyecto de ejemplo completo para obtener más contexto.

Una vez que se han agregado los datos al modelo, se deben usar migraciones para aplicar los cambios.

Sugerencia

Si necesita aplicar migraciones como parte de una implementación automatizada, puede crear un script SQL que se pueda obtener una vista previa antes de la ejecución.

Como alternativa, puede usar para crear una nueva base de datos que contenga los datos de ed. Por ejemplo, para una base de datos de prueba o cuando se usa el proveedor en memoria o cualquier base de datos que no sea context.Database.EnsureCreated() de relación. Tenga en cuenta que si la base de datos ya existe, EnsureCreated() no actualizará el esquema ni los datos de ed en la base de datos. En el caso de las bases de datos relacionales, no EnsureCreated() debe llamar a si tiene previsto usar migraciones.

Limitaciones de los datos de ed. del modelo

Este tipo de datos de ed se administra mediante migraciones y el script para actualizar los datos que ya están en la base de datos debe generarse sin conectarse a la base de datos. Esto impone algunas restricciones:

  • El valor de clave principal debe especificarse incluso si normalmente lo genera la base de datos. Se usará para detectar cambios de datos entre migraciones.
  • Los datos previamente seeded se quitarán si la clave principal se cambia de alguna manera.

Por lo tanto, esta característica es más útil para los datos estáticos que no se espera que cambien fuera de las migraciones y no depende de nada más en la base de datos, por ejemplo códigos POSTALes.

Si el escenario incluye cualquiera de los siguientes, se recomienda usar la lógica de inicialización personalizada descrita en la última sección:

  • Datos temporales para pruebas
  • Datos que dependen del estado de la base de datos
  • Datos que son grandes (los datos de edación se capturan en instantáneas de migración y los datos grandes pueden dar lugar rápidamente a archivos enormes y un rendimiento degradado).
  • Datos que necesitan que la base de datos genere valores de clave, incluidas las entidades que usan claves alternativas como identidad
  • Datos que requieren una transformación personalizada (que no se controla mediante conversiones de valores),como algún hash de contraseña
  • Datos que requieren llamadas a la API externa, como la creación de roles de ASP.NET Core identity y la creación de usuarios

Personalización de la migración manual

Cuando se agrega una migración, los cambios en los datos especificados con se transforman en HasData llamadas a , y InsertData()UpdateData()DeleteData() . Una manera de evitar algunas de las limitaciones de es agregar manualmente estas llamadas o operaciones HasDataHasData a la migración en su lugar.

migrationBuilder.InsertData(
    table: "Blogs",
    columns: new[] { "Url" },
    values: new object[] { "http://generated.com" });

Lógica de inicialización personalizada

Una manera sencilla y eficaz de realizar la edación de datos es usar antes DbContext.SaveChanges() de que la lógica de aplicación principal comience a ejecutarse.

using (var context = new DataSeedingContext())
{
    context.Database.EnsureCreated();

    var testBlog = context.Blogs.FirstOrDefault(b => b.Url == "http://test.com");
    if (testBlog == null)
    {
        context.Blogs.Add(new Blog { Url = "http://test.com" });
    }

    context.SaveChanges();
}

Advertencia

El código de eding no debe formar parte de la ejecución normal de la aplicación, ya que esto puede causar problemas de simultaneidad cuando se ejecutan varias instancias y también requeriría que la aplicación tenga permiso para modificar el esquema de la base de datos.

En función de las restricciones de la implementación, el código de inicialización se puede ejecutar de maneras diferentes:

  • Ejecución local de la aplicación de inicialización
  • Implementar la aplicación de inicialización con la aplicación principal, invocar la rutina de inicialización y deshabilitar o quitar la aplicación de inicialización.

Normalmente, esto se puede automatizar mediante perfiles de publicación.