Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 19 de marzo de 2019
Entity Framework Core Vamos con un post rapidito, al hilo de una pregunta que planteaba el amigo Javier  R. vía el formulario de contacto del blog, sobre el artículo donde veíamos las shadow properties de Entity Framework Core, cuya respuesta creo que puede ser interesante para alguien más.

En concreto, la duda le surgía al combinar las capacidades de data seeding de EF con las propiedades ocultas, y básicamente era:
Dado que las shadow properties no existen en la entidad, ¿cómo podemos establecerlas en el momento del seeding de datos?
Bien, aunque no es fácil de descubrir de forma intuitiva, la solución es bastante sencilla. Si nos fijamos en el intellisense del método que utilizamos para el poblado de datos, HasData(), podemos observar varias sobrecargas; por ejemplo, en la siguiente captura se puede ver la información mostrada al invocar este método para la entidad Friend:

Intellisense en HasData()


Fijaos que, aunque estemos hablando de la entidad Friend, HasData() admite la posibilidad de enviarle cualquier tipo de objeto, y ahí es donde está la clave. Podemos enviarle simples objetos anónimos, de los que extraerá el valor para sus propiedades; dado que no existe un tipado específico, podemos introducir en ellos todas las propiedades que nos interesen poblar, incluidas las shadow properties de la entidad:
// Entidad:
public class Friend
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}

// Contexto de datos:
public class FriendsContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Friend>()
            .Property<DateTime>("UpdatedAt");
        builder.Entity<Friend>()
            .Property<string>("UpdatedBy")
            .HasMaxLength(20);

        // Seeding con objetos anónimos:
        builder.Entity<Friend>().HasData(
            new { Id = 1, Name = "Lisa Smith", Birthdate = new DateTime(1984, 3, 22), 
                  UpdatedAt = DateTime.Now, UpdatedBy = "jmaguilar" 
            },
            new { Id = 2, Name = "Malcolm Wesser", Birthdate = new DateTime(1970, 9, 1), 
                  UpdatedAt = DateTime.Now, UpdatedBy = "jmaguilar" 
            }
        );
    }
    ...
}
Fácil, ¿eh?

Hey, pero... ¿y si no me gustan los objetos anónimos?

Si eres de los que prefieren hacer funambulismo sobre la red de protección que nos proporciona el tipado fuerte con chequeo en compilación, también hay una solución para ti ;)

En este caso, bastaría con crear una clase con los campos que queramos, y enviar instancias a HasData() como si se tratara de objetos anónimos.
public class FriendsContext : DbContext
{
    private class SeedFriend
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime Birthdate { get; set; }

        public DateTime UpdatedAt { get; set; }
        public string UpdatedBy { get; set; }
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Friend>()
            .Property<DateTime>("UpdatedAt");
        builder.Entity<Friend>()
            .Property<string>("UpdatedBy")
            .HasMaxLength(20);

        // Seeding con objetos de tipos arbitrarios:
        builder.Entity<Friend>().HasData(
            new SeedFriend { Id = 1, Name = "Lisa Smith", Birthdate = new DateTime(1984, 3, 22), 
                  UpdatedAt = DateTime.Now, UpdatedBy = "jmaguilar" 
            },  
            new SeedFriend { Id = 2, Name = "Malcolm Wesser", Birthdate = new DateTime(1970, 9, 1), 
                  UpdatedAt = DateTime.Now, UpdatedBy = "jmaguilar" 
            }
        );
    }
}
Espero que os sea de utilidad :)

Publicado en: www.variablenotfound.com.

Aún no hay comentarios, ¡sé el primero!