Anexsoft | Blog y dictado de cursos de Tecnología

En este encontrarás tutoriales de tecnología como PHP, ASP.NET MVC, Front-End, entre otros y cursos exigentes de modalidad online que te ayudarán a crecer profesionalmente.

ASP.NET MVC: insertando/actualizando con relaciones de mucho a mucho
Actualizado el 21 Enero, 2016 y leído 18,920 veces
Calificación: 9.56 / 10

ASP.NET MVC: insertando/actualizando con relaciones de mucho a mucho

Anexsoft

Creando la acción para nuestro formulario

Vamos a comenzar creando nuestra acción Crud del controlador Home, este será el encargado de registrar nuevos alumnos o actualizar, de esta manera evitamos crear 2 acciones (Registrar, Actualizar) y hacemos que el mantenimiento del código se realice a un mismo formulario.

public ActionResult Crud(int id = 0)
{
    ViewBag.Cursos = curso.Todo();
    return View(
        id > 0 ? alumno.Obtener(id)
                : alumno
    );
}

Este acción recibe un parámetro opcional, el cual es el ID, si no ha sido especificado quiere decir que nuestro formulario entra en modo de Nuevo Registro, del caso contrario buscamos en la base de datos dicho registro y el formulario entra en modo de Actualización.

Adicionalmente: hemos usado un ViewBag, para guardar todos los cursos de la base de datos, ya que debemos elegir entre todos que cursos quiere el alumno.

public List<Curso> Todo() 
{
    var cursos = new List<Curso>();
    try
    {
        using (var context = new TestContext())
        {
            cursos = context.Curso.ToList();
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }

    return cursos;
}

Image title

 

La vista de nuestro formulario

Hemos usado los HTML Helper para crear los textbox y demás controles que tengamos.

@model Model.Alumno
@{
    ViewBag.Title = (Model.id > 0 ? Model.Nombre + " " + Model.Apellido : "Nuevo registro");
    List<Model.Curso> cursos = ViewBag.Cursos;
}

<ol class="breadcrumb">
  <li><a href="~/">Alumnos</a></li>
  <li class="active">@(Model.id > 0 ? Model.Nombre + " " + Model.Apellido : "Nuevo registro")</li>
</ol>

@using (Html.BeginForm("Guardar", "Home", FormMethod.Post, new { id = "frm-alumno" })) 
{
    @Html.HiddenFor( x => x.id )
    <div class="panel panel-default">
      <div class="panel-heading">Información personal</div>
      <div class="panel-body">
        <div class="form-group">
            @Html.LabelFor(x => x.Nombre)
            @Html.TextBoxFor(x => x.Nombre, new { @class = "form-control" })
        </div>
        <div class="form-group">
            @Html.LabelFor( x => x.Apellido)
            @Html.TextBoxFor(x => x.Apellido, new { @class = "form-control" })
        </div>
      </div>
    </div>

    <div class="panel panel-default">
      <div class="panel-heading">Asignaturas</div>
      <div class="panel-body">
        <ul class="list-group">
        @foreach (var c in cursos) 
        {
            var tomado = false;
            foreach (var c2 in Model.Cursos) 
            {
                if (c.id == c2.id) 
                {
                    tomado = true;
                    break;
                }
            }
            <li class="list-group-item">
                <label><input type="checkbox" @(tomado ? "checked" : "") name="cursos" value="@c.id" /> @c.Nombre</label>
            </li>
        }
        </ul>
      </div>
    </div>
    
    <div class="text-right">
        <button type="submit" class="btn btn-primary">Guardar</button>
    </div>
}

Un detalle muy importante, los cursos que disponemos para elegir tienen asignado un name "cursos" y lo vamos a pasar a nuestra acción como si fuera un array, ya que solo nos interesa capturar los ids de los cursos seleccionados.

 

La acción para registrar/actualizar un alumno

Nuestra acción esta preparada ya sea para registrar o actualizar, ya que en nuestra clase Alumno hemos implementado un método llamado Guardar que hará esa lógica por nosotros.

public ActionResult Guardar(Alumno model, int[] cursos = null) 
{
    if (cursos != null) 
    {
        foreach (var c in cursos)
            model.Cursos.Add(new Curso { id = c });
    }

    model.Guardar();

    return Redirect("~/home/crud/" + model.id);
}

 

Implementando el método Guardar en la clase Alumno

Para determinar si un alumno es nuevo o queremos actualizarlo solo basta jugar con su id y preguntar si es > 0 "Actualizar", del caso contrario "Nuevo registro".

public void Guardar()
{
    try
    {
        using (var context = new TestContext())
        {
            if (this.id == 0)
            {
                context.Entry(this).State = EntityState.Added;
            }
            else 
            {
                context.Database.ExecuteSqlCommand(
                    "DELETE FROM AlumnoCurso WHERE Alumno_id = @id",
                    new SqlParameter("id", this.id)
                );

                var cursoBK = this.Cursos;

                this.Cursos = null;
                context.Entry(this).State = EntityState.Modified;
                this.Cursos = cursoBK;
            }

            foreach (var c in this.Cursos)
                context.Entry(c).State = EntityState.Unchanged;

            context.SaveChanges();
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
}

 

Vamos analizar un poco el siguiente código, primero cuando la condición dada se da para un nuevo registro.

if (this.id == 0)
{
    context.Entry(this).State = EntityState.Added;
}
else 
{
    /* Lógica para actualizar */
}

foreach (var c in this.Cursos)
    context.Entry(c).State = EntityState.Unchanged;

context.SaveChanges();
  1. Primero registramos en nuestro contexto la clase con la que queremos trabajar, y actualizamos su estado (EntityState.Added) diciendole que se trata de un nuevo registro. 

  2. Luego hacemos un foreach para recorrer los cursos seleccionados por el Usuario y lo agregamos al contexto actual indicandole que su estados es Sin Cambios, para evitar que registre o actualice un curso, del caso contrario lo agregue a la tabla que tiene en común, la cual es AlumnoCursos.

  3. Image titleAl final guardamos los cambios haciendo context.SaveChanges();

 

Ahora vamos analizar el código para cuando al condición se da para un registro que ya existe y queremos actualizarlo.

if (this.id == 0)
{
    /* logica para registro nuevo */
}
else 
{
    context.Database.ExecuteSqlCommand(
        "DELETE FROM AlumnoCurso WHERE Alumno_id = @id",
        new SqlParameter("id", this.id)
    );

    var cursoBK = this.Cursos;

    this.Cursos = null;
    context.Entry(this).State = EntityState.Modified;
    this.Cursos = cursoBK;
}

foreach (var c in this.Cursos)
    context.Entry(c).State = EntityState.Unchanged;

context.SaveChanges();
  1. Lo primero que hago es ejecutar una consulta para eliminar todos los cursos que el usuario haya elegido previamente, de esta manera dicha relación no existe.

  2. Luego hago una copia de los cursos que ha elegido el usuario y lo guardo en al variable cursoBK.

  3. Hice la copia de los cursos, porque al intentar agregar la entidad Alumno al nuevo contexto este arrojaría un error indicandome que el modelo ingresado actualmente en la base de datos no tiene dichos cursos.

  4. Luego altero el estado de la entidad y le digo que es del tipo EntityState.Modified.

  5. Hago el mismo proceso con el foreach para indicarle a los cursos elegidos que deben ser agregados a la tabla que mantiene relación con el Alumno y sus cursos.

  6. Guardo los cambios, context.SaveChanges().

 

Recomiendo altamente ver el VIDEO para enriquecer los conocimientos, y por favor cualquier DUDA, realicen las preguntas que crean conveniente.

 

Partes:

¡Adquiera ya!

  • Código de fuente de Red Social desarrollada en ASP.NET MVC

    Código de fuente de Red Social desarrollada en ASP.NET MVC
  • Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#

    Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#
  • Software de Venta e Inventario hecho en PHP y Codeigniter

    Software de Venta e Inventario hecho en PHP y Codeigniter

Últimas publicaciones

Encuesta

¿Cómo nos conociste?

Síguenos

Estudia con nosotros y crece profesionalmente

Nuestros cursos han sido hecho en base a lo que demanda el mercado hoy en día.
La experiencia obtenida es la de un ambiente laboral.

Anexsoft
© 2017 Anexsoft, blog y cursos online de TI.