martes, 12 de marzo de 2019

A grandes rasgos, se trata de la capacidad de este framework para gestionar propiedades de una entidad que existen en el almacén datos pero no en la clase .NET que la representa en el mundo de los objetos.
De forma intuitiva podemos saber que esto ya existía en las versiones clásicas de Entity Framework. Por ejemplo, cuando introducíamos una propiedad de navegación entre dos entidades sin usar una clave foránea de forma explícita, el propio marco de trabajo creaba, por convención, una columna en la base de datos para almacenar dicha referencia, como en el siguiente escenario:
public class Friend
{
public int Id { get; set; }
public string Name { get; set; }
// Se crea una columna CountryId en la base de datos,
public Country Country { get; set; } // pero no existe en la entidad.
}
El valor de dicha columna CountryId
no podía ser manipulada de forma directa porque se trataba de información usada internamente para gestionar las relaciones y su valor era obtenido y actualizado de forma transparente para nosotros.Pues bien, Entity Framework Core aporta la capacidad para gestionar este tipo de campos "ocultos" para servir a nuestros propios intereses. De esta forma, podríamos añadir a una entidad propiedades que no tienen por qué estar visibles en la clase .NET en forma de propiedades; un ejemplo podría ser el clásico "IsDeleted" cuando implementamos borrado lógico, o información de auditoría como los tradicionales "UpdatedAt" o "UpdatedBy".
Definición de propiedades ocultas
La definición de shadow properties sólo puede realizarse utilizando el API fluido de configuración disponible a través del objetoModelBuilder
suministrado al método OnModelCreating()
del contexto de datos.Por ejemplo, el siguiente bloque de código añade a la entidad
Friend
las propiedades ocultas UpdatedAt
y UpdatedBy
, que podrían sernos de utilidad para almacenar información interna de auditoría:// Entidad:
public class Friend
{
public int Id { get; set; }
public string Name { get; set; }
}
// Contexto de datos:
public class FriendsContext : DbContext
{
public DbSet<Friend> Friend { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Friend>()
.Property<DateTime>("UpdatedAt");
builder.Entity<Friend>()
.Property<string>("UpdatedBy").HasMaxLength(80);
}
}
Y esto es todo, así de sencilla es la creación de shadow properties :)Consultar o establecer el valor de una propiedad oculta de una entidad
Dado que estas propiedades no aparecen en las clases .NET que representan a las entidades de datos, no podemos acceder a sus valores utilizando expresiones comoobjeto.Propiedad
desde nuestro código. Sus valores están gestionados directamente por el change tracker de Entity Framework, por lo que debemos recurrir a él para hacerlo.Por ejemplo, el siguiente código muestra cómo acceder a las propiedades ocultas de una entidad obtenida previamente:
var friend = ctx.Friends.FirstOrDefault();
if(friend != null)
{
var name = friend.Name;
var updatedBy = ctx.Entry(friend).Property<string>("UpdatedBy").CurrentValue;
var updatedAt = ctx.Entry(friend).Property<DateTime>("UpdatedAt").CurrentValue;
Console.WriteLine($"{name} was updated by {updatedBy} at {updatedAt}");
}
De la misma forma, para actualizar el valor de las shadow properties, tendremos que esta la misma shadow property podríamos hacerlo como sigue:var friend = ctx.Friends.FirstOrDefault();
if(friend != null)
{
ctx.Entry(friend).Property<string>("UpdatedBy").CurrentValue = "John Smith";
ctx.Entry(friend).Property<DateTime>("UpdatedAt").CurrentValue = DateTime.Now;
ctx.SaveChanges();
}
Incluir shadow properties en expresiones de consulta
Obviamente, el hecho de que no tengamos propiedades en la entidad para acceder a estos valores condiciona también la forma en que debemos utilizarlos desde LINQ en los predicados o criterios de consultas.Pero de nuevo, tenemos una fórmula bastante sencilla para conseguirlo obteniendo una referencia válida para el árbol de expresión a través del método
EF.Property()
. En el siguiente ejemplo vemos cómo filtrar las entidades para obtener sólo aquellas actualizadas durante el último minuto:var since = DateTime.Now.AddMinutes(-1);
var friendsRecentlyUpdated = ctx.Friends
.Where(b => EF.Property<DateTime>(b, "UpdatedAt") > since);
Publicado en Variable not found.
Aún no hay comentarios, ¡sé el primero!
Enviar un nuevo comentario