Relacionando tablas con AspNetUsers. Referencia a usuarios desde otra tabla.

Con Entity Framework podemos crear relaciones entre nuestras tablas. Es bien sencillo utilizar propiedades navigacionales para crear llaves foráneas y poder relacionar una tabla con otra. Esto es importante porque nos permite evitar repetir información. Así, si tenemos una tabla de facturas y una tabla de clientes, entonces podemos tener una relación entre estas dos tablas, de tal manera que en la tabla de facturas tengamos un campo, ClientId, el cual contiene una referencia a nuestro cliente en la tabla de clientes.

Cuando creamos una aplicación de ASP.NET con el sistema de autenticación individual por defecto, podemos hacer la relación de la tabla AspNetUsers (la tabla que contiene nuestros usuarios) con cualquier otra tabla de nuestra aplicación. Vamos a hacer esto.

En esta entrada haré uso de: Visual Studio 2017 Community Edition, ASP.NET Core 2.0 y Entity Framework Core 2.0.

Lo primero que necesitamos es un proyecto de ASP.NET con sistema de autenticación individual. Si acabas de crear el proyecto, haz un add-migration en el Package Manager Console en Visual Studio:

add-migration Initial

Luego, haz el update-database:

Update-Database

Ahora lo que vamos a hacer es crear un nuevo modelo, factura, el cual va a contener informaciones acerca de ventas de nuestro sistema, y además nos va a permitir guardar una referencia hacia un usuario de la tabla AspNetUsers:


public class Invoice
{
public int Id { get; set; }
public decimal Total { get; set; }
public string Concept { get; set; }
public string ClientId { get; set; }
public ApplicationUser Client { get; set; }
}

Como puedes ver, en este modelo tenemos la columna ClientId, la cual sirve de llave foránea para la propiedad navigacional Client. Fíjate que estamos siguiendo la convención EntidadId, donde en nuestro caso la Entidad está representada por la propiedad llamada Client, que es del tipo ApplicationUser. Esto es suficiente para decirle a Entity Framework Core 2.0 que queremos una relación entre la tabla de Invoices y la tabla de AspNetUsers. Ahora, vamos a colocar el DbSet correspondiente en nuestro ApplicationDbContext:


public DbSet<Invoice> Invoices { get; set; }

Ya con esto podemos agregar una nueva migración:

Add-Migration Invoices

Y luego podemos hacer un Update-Database. Vamos entonces a hacer una prueba, insertemos un registro en la tabla de Invoices y coloquemos nuestro usuario en el campo de ClientId. Si no lo has hecho, regístrate y logueate en tu aplicación. Luego, preparemos una clase para que puedas utilizar el ApplicationDbContext y el UserManager. Para este ejemplo, yo utilizaré el HomeController. Modifica el constructor del HomeController de la siguiente manera:


private readonly ApplicationDbContext context;
private readonly UserManager<ApplicationUser> userManager;

public HomeController(ApplicationDbContext context,
UserManager<ApplicationUser> userManager)
{
  this.context = context;
  this.userManager = userManager;
}

De este modo, estamos aprovechando la inyección de dependencias para utilizar el Context y el UserManager. Ahora, modifica la acción About con el siguiente código:


public IActionResult About()
{
  if (User.Identity.IsAuthenticated)
  {
    var invoice = new Invoice();
    invoice.Concept = "Computer";
    invoice.Total = 500;
    invoice.ClientId = userManager.GetUserId(HttpContext.User);
    context.Add(invoice);
    context.SaveChanges();
  }

ViewData["Message"] = "Your application description page.";

return View();
}

En el código dentro del condicional If, podemos ver que estamos instanciando una factura, y la estamos insertando en la base de datos. Podemos ver que estamos asignando el usuario actual al campo ClientId. Corre dicho código yendo a la página de About mientras estás logueado. Ya con esto hemos insertado un registro. Para poder ver que ha funcionado, solamente debemos realizar la siguiente sentencia con Entity Framework:


var invoices = context.Invoices.Include(x => x.Client).ToList();

La cual nos traerá todas las facturas con la información de los Clientes (usuarios). Podemos también hacer un query a nivel de la base de datos para revisar esto, en el caso de SQL Server, podemos hacer un inner join:


Select AspNetUsers.Email, Concept, Total
from Invoices
inner join AspNetUsers
ON Invoices.ClientId = AspNetUsers.Id

Resumen

Para relacionar la tabla AspNetUsers con cualquier otra tabla de tu aplicación, simplemente debes colocar la llave foránea en el modelo de la tabla con la cual quieres relacionar AspNetUsers.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s