You are on page 1of 19

1

Desarrollo en Capas .Net (Parte 1)




Aspectos a considerar
Se usara Visual Studio 2010 y Sql Express 2008.
Se realizara con los lenguajes de C# y VB.Net.(pero solo se explicara con c#)
Se usara la versin 4.1 de Entity Framework
Se usara un generador de plantillas T4.

En este primer articulo veremos como generar nuestro modelo de datos .edmx de entity framework y veremos como
usar DbContext Generator para generar nuestro contexto y clases poco de nuestro modelo. Cual es la finalidad de esto
separa las entidades de la persistencia para poder usar estas en otras capas. Para hacer esto necesitaremos la
versin ADO.NET Entity Framework 4.1 tambien necesitaremos el generador de plantillas para c# EF 4.x DbContext
Generator for C# o para vb.net EF 4.x DbContext Generator for VB.NET

Lo que aremos a lo largo de todo el ejemplo sera dividir el proyecto en capas para poder notar todas las ventajas que esto
aporta entre ellas reutilizacin de cdigo, mejor mantenimiento de la aplicacin, separacin de responsabilidades etc.

La siguiente imagen muestra la estructura que tendr nuestro proyecto final y la comunicacin que abra entre las diferentes
capas.



Para todo el ejemplo usare una base de datos llamada Estudiantes que tiene el siguiente diseo.

2


Lo primero sera crear un proyecto en blanco y agregar una biblioteca de clases llamadaDataAcces.



Ahora vamos a generar el modelo de nuestra base de datos para eso agregamos un nuevo elemento y elegimos ADO.NET
Entity Data Model.


Elegimos generar desde la base de datos.

3


Especificamos la cadena de conexin hacia la base de datos.



Ahora seleccionamos los objetos de la base de datos que queremos modelar en este caso seleccionamos las 3 tablas.



Con esto tendremos nuestro modelo de la base de datos.
4


Ahora vamos a generar nuestras clases poco haciendo uso del generador de DbContext. Para esto hacemos clic derecho en
un espacio en blanco del modelo y elegimos Agregar elemento de generacin de cdigo.



Elegimos ADO.NET DbContext Generator(tienen que haberlo instalado antes).
5




Si aparece un cuadro de advertencia eligen no mostrar este mensaje de nuevo y aceptar. Esto agregara 2 plantillas(cuyos
nombres terminan en .tt) a su proyecto.



La plantilla Students.Context.tt cre una clase DbContext conteniendo las colecciones de entidades y la
plantilla Students.tt cre clases separadas para cada tabla.

Para que el modelo DbContext funcione necesita de la version 4.1 de entity framework(tienen que instalarlo) as que
agregaremos la dll para eso agregamos una referencia al proyecto y buscamos la dll en la ruta que se instalo que por lo
general es C:\Archivos de programa\Microsoft ADO.NET Entity Framework 4.1\Binaries
6




Ahora lo que aremos es mover la plantilla Students.tt la que contiene las clases de cada tabla a otro proyecto biblioteca de
clases en este caso llamado Entities.



Para que esta plantilla funcione ahora que lo hemos movido a una proyecto nuevo tendremos que configurar la linea que
apunta hacia el modelo EDMX para eso damos doble clic en la platilla Students.tt y cambiamos la ruta de string
InputFile para que apunte hacia el modeloEDMX que se encuentra en el proyecto DataAcces.



Ahora cambiaremos el espacio de nombres de la platilla Students.Context.tt ya que las clases entidades las movimos hacia
7

el proyecto Entities tenemos que modificar el espacio de nombres de la plantilla Students.Context.tt para esto abrimos la
ventana de propiedades de la plantilla y establecemos el espacio de nombres en Entities.





Por ultimo lo que tenemos que hacer es agregar una referencia del proyecto Entities en el proyecto DataAcces.



Nota: En el caso del proyecto vb.net en la clase de la platilla Students.Context.vb es necesario agregar un Imports Entities
para que el contexto reconozca las clases entidad.

Con esto terminamos la primera parte de nuestro Proyecto. Lo que hemos hecho es crear el modelo de nuestra base de
datos y tambin hemos generado el contexto y las clases entidad del modelo y tambin hemos separado las clases entidad
en un proyecto aparte para poder usar estas clases en las dems capas, ya que como lo dije al principio la finalidad de todos
esto es separar las entidades de la persistencia.

Desarrollo en Capas .Net (Parte 2) - Capa de Datos
8

En el articulo anterior creamos nuestro modelo EDMX de nuestra base de datos y tambin creamos nuestras clases
entidades y las dividimos en una capa aparte llamada Entities.

Pues bien en este segundo articulo desarrollaremos el cdigo que tendr nuestra capa de datos(DataAcces).

En la capa de datos(DataAcces) es donde tendremos todas las query a nuestra base de datos.

Antes de empezar a programar en nuestra capa de datos primero agregaremos una clase llamada NotaAlumno en nuestra
capa Entities(ya veremos para que nos servira).

public class NotaAlumno
{
public int NotId { get; set; }
public string AluNombre { get; set; }
public string MatNombre { get; set; }
public decimal NotNota { get; set; }
}

Entonces nuestra capa Entities nos quedara de la siguiente manera.



Como pueden observar nuestra capa Entities tendr nuestras clases entidades que generamos en el articulo anterior y la
nueva clase que acabamos de agregar.
Ahora si empecemos con el cdigo que tendr nuestra capa de datos(DataAcces) lo que aremos es que por cada clase
entidad agregaremos una clase a nuestra capa de datos(DataAcces) y dentro de estas tendremos las diferentes query a
nuestra base de datos.
Agreguemos la primera clase que se llamara AlumnoDAL.
public class AlumnoDAL
{
public static List<Alumno> CargarAlumnos()
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
return bd.Alumno.ToList();
}
}

public static bool Existe(int id)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from al in bd.Alumno where al.AluId == id select al).Count();
9

if (query == 0)
return false;
else
return true;
}
}

public static Alumno IdAlumno(int id)
{
Alumno alum = new Alumno();
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from al in bd.Alumno
where al.AluId == id
select al).Single();

alum.AluId = query.AluId;
alum.AluNombre = query.AluNombre;
alum.AluApellido = query.AluApellido;
alum.AluEdad = query.AluEdad;
alum.AluDireccion = query.AluDireccion;
}
return alum;
}

public static Alumno CreateAlumno(Alumno alum)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
Alumno al = new Alumno();
al.AluNombre = alum.AluNombre;
al.AluApellido = alum.AluApellido;
al.AluEdad = alum.AluEdad;
al.AluDireccion = alum.AluDireccion;
bd.Alumno.Add(al);
bd.SaveChanges();
alum.AluId = al.AluId;
}
return alum;
}

public static Alumno UpdateAlumno(Alumno alum)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from al in bd.Alumno
where al.AluId == alum.AluId
select al).Single();

query.AluNombre = alum.AluNombre;
query.AluApellido = alum.AluApellido;
query.AluEdad = alum.AluEdad;
query.AluDireccion = alum.AluDireccion;
bd.SaveChanges();
}
return alum;
}

}
10


Dentro de esta clase tenemos una serie de mtodos que ahorita explicare.
CargarAlumnos() Este mtodo lo nico que hace es retornar todos los registros de la tabla Alumno.
Existe() Este mtodo se encarga de comprobar si un alumno existe por medio del id retornafalse si no existe y true si ya
existe.
IdAlumno() Este mtodo lo que hace es retornar los datos de un alumno tambin por medio del id.

CreateAlumno() Este mtodo agrega un nuevo alumno a nuestra base de datos y luego de agregarlo retornamos la entidad
osea el alumno agregado.

UpdateAlumno() Este mtodo actualiza un alumno utilizamos el id para actualizar los datos y luego tambin retornamos la
entidad osea el alumno actualizado.


Ahora agreguemos una clase llamada NotaDal.
public class NotaDal
{
public static bool Existe(int idalum, int idmat)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from not in bd.Nota where not.AluId == idalum && not.MatId == idmat select not).Count();
if (query == 0)
return false;
else
return true;
}
}

public static Nota IdNota(int id)
{
Nota not = new Nota();
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from n in bd.Nota
where n.NotId == id
select n).Single();

not.NotId = query.NotId;
not.AluId = query.AluId;
not.MatId = query.MatId;
not.NotNota = query.NotNota;
}
return not;
}

public static Nota CreateNota(Nota not)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
Nota n = new Nota();
n.AluId = not.AluId;
n.MatId = not.MatId;
n.NotNota = not.NotNota;
bd.Nota.Add(n);
bd.SaveChanges();
not.NotId = n.NotId;
11

}
return not;
}

public static Nota UpdateNota(Nota not)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = (from n in bd.Nota
where n.NotId == not.NotId
select n).Single();

query.AluId = not.AluId;
query.MatId = not.MatId;
query.NotNota = not.NotNota;
bd.SaveChanges();
}
return not;
}
}

Dentro de esta clase encontramos los siguientes mtodos.

Existe() Este mtodo se encargara de comprobar si una nota ya existe por medio del id del alumno y el id de la materia este
mtodo nos ayudara para que un alumno solo pueda agregar una nota por materia.
IdNota() Este mtodo lo que hace es retornar los datos datos de un registro por medio del id.
CreateNota() Este mtodo agrega un registro a la tabla nota y luego retornamos la entidad osea el registro agregado.
UpdateNota() Este mtodo actualiza una nota utilizamos el id para actualizar los datos y luego tambin retornamos la
entidad osea el registro actualizado.
Ahora agreguemos una clase llamada MateriaDal.
public class MateriaDal
{
public static List<Materia> CargarMaterias()
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
return bd.Materia.ToList();
}
}
}

Dentro de esta clase solo tenemos un mtodo CargarMaterias() que lo nico que hace es retornar todos los registros de la
tabla materia.

Ahora agreguemos una clase llamada NotaAlumnoDal.
public class NotaAlumnoDal
{
public static List<NotaAlumno> CargarNotas()
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = from not in bd.Nota
select new NotaAlumno
{
NotId = not.NotId,
12

AluNombre = not.Alumno.AluNombre,
MatNombre = not.Materia.MatNombre,
NotNota = not.NotNota
};
return query.ToList();
}
}

public static List<NotaAlumno> NotasAlumno(int id)
{
using (EstudiantesEntities bd = new EstudiantesEntities())
{
var query = from not in bd.Nota
where not.AluId == id
select new NotaAlumno
{
NotId = not.NotId,
AluNombre = not.Alumno.AluNombre,
MatNombre = not.Materia.MatNombre,
NotNota = not.NotNota
};

return query.ToList();
}
}
}

Dentro de esta clase encontramos los siguientes mtodos.
CargarNotas() este mtodo retorna todos los registros de la tabla nota.
NotasAlumno() este mtodo retorna todas las notas de un alumno es por eso que hacemos uso del id del alumno para solo
devolver solo las notas de un alumno.
En esta clase hicimos uso de la clase que agregamos a nuestra capa Entities llamadaNotaAlumno si se fijan en la query que
hacemos a la tabla nota hacemos uso de las propiedades de la clase para en vez de que nos muestre el id del alumno y la
materia nos muestre el nombre del alumno y de la materia, haciendo tambin uso de las propiedades de navegacin que
existen ente las tablas.
Importante que dentro de cada clase que agregamos a nuestra capa de datos(DataAcces) necesitamos el espacio de
nombres Entities para poder hacer uso de nuestras clases entidades.
using Entities;

Eso seria todo en nuestra capa de datos, al final nuestro proyecto nos quedara de la siguiente manera.
13



Resumiendo lo que hicimos agregamos 4 clases(DAL) a nuestra capa de datos(DataAcces) una por cada clase entidad y
dentro de estas tenemos las diferentes query hacia la base de datos.

Desarrollo en Capas .Net (Parte 3) - Capa de Negocio

La capa de negocio(BussinesLayer) se comunicara con la capa de presentacin, para recibir las solicitudes y presentar los
resultados, y con la capa de datos para almacenar o recuperar datos de la base de datos.
Algo que seguro a mas de uno les traer molestias de esta capa de negocio sera que la mayora de las operaciones sern un
pasamano, ya que esta retorna las operaciones de la capa de datos y las devolver en la capa de presentacin, pero no
siempre sera as en otros casos se vera la importancia de esta capa sobre todo en aplicaciones complejas.

Empecemos agregando una clase llamada AlumnoBL.
public class AlumnoBL
{
public static List<Alumno> CargarAlumnos()
{
return AlumnoDAL.CargarAlumnos();
}

public static Alumno IdAlumno(int id)
{
return AlumnoDAL.IdAlumno(id);
}

public static Alumno Save(Alumno alum)
{
if (AlumnoDAL.Existe(alum.AluId))
return AlumnoDAL.UpdateAlumno(alum);
else
return AlumnoDAL.CreateAlumno(alum);
}
14

}
Dentro de la clase tenemos los siguientes mtodos.
CargarAlumnos() Este mtodo retorna todos los registros de la tabla Alumno.
IdAlumno() Este metodo retorna los datos de un alumno por medio del id.
Save() Este mtodo valida si el registro existe por medio del id y dependiendo de esto actualiza o agrega un registro.

Ahora agreguemos una clase llamada MateriaBL.
public class MateriaBL
{
public static List<Materia> CargarMaterias()
{
return MateriaDAL.CargarMaterias();
}
}
Dentro de esta clase solo tenemos un mtodo CargarMaterias() que lo nico que hace es retornar todos los registros de la
tabla materia.
Ahora agreguemos una clase llamada NotaBL.
public class NotaBL
{
public static Nota IdNota(int id)
{
return NotaDAL.IdNota(id);
}

public static bool CreateNota(Nota not)
{
if (NotaDAL.Existe(not.AluId, not.MatId))
return true;
else
{
NotaDAL.CreateNota(not);
return false;
}
}

public static bool UpdateNota(Nota not)
{
if (NotaDAL.Existe(not.AluId, not.MatId))
{
NotaDAL.UpdateNota(not);
return true;
}
else
{
return false;
}
}
}

Dentro de esta clase encontramos los siguientes mtodos.
IdNota() Este mtodo lo que hace es retornar los datos datos de un registro por medio del id.
CreateNota() Este mtodo valida si un registro existe por medio del id del alumno y el id de la materia si existe retorna
true, y si no existe crea el registro y retorna false. Validamos si el registro no existe para que un alumno solo pueda agregar
una nota por materia..
15

UpdateNota() Este mtodo igual que el anterior valida si el registro existe por medio del id del alumno y id de la materia
solo que si el registro existe actualizamos el registro y retornamos true, y si no existe retornamos false.

Ahora agreguemos una clase llamada NotaAlumnoBL.
public class NotaAlumnoBL
{
public static List<NotaAlumno> CargarNotas()
{
return NotaAlumnoDAL.CargarNotas();
}

public static List<NotaAlumno> NotasAlumno(int id)
{
return NotaAlumnoDAL.NotasAlumno(id);
}
}

Dentro de esta clase encontramos los siguientes mtodos.
CargarNotas() este mtodo retorna todos los registros de la tabla nota.

NotasAlumno() este mtodo retorna todas las notas de un alumno es por eso que hacemos uso del id del alumno para solo
devolver solo las notas de un alumno.
Importante que dentro de cada clase que agregamos a nuestra capa de negocio(BussinesLayer) necesitamos agregar
referencias hacia las capas DataAccesy Entities.
using DataAcces;
using Entities;

Eso seria todo en nuestra capa de negocio(BussinesLayer) al final nuestro proyecto quedara de la siguiente manera.
16



Desarrollo en Capas .Net (Parte 4) - Capa Presentacion

La capa presentacin(presentation) es la que ve el usuario (tambin se la denomina "capa de usuario"), presenta el sistema
al usuario, le comunica la informacin y captura la informacin del usuario en un mnimo de proceso (realiza un filtrado
previo para comprobar que no hay errores de formato).

En este ultimo articulo es donde veremos como se comunican las diferentes capas entre si.



Diseo de la aplicacin.
17




Cargar Alumnos y Materias.
//cargo alumnos en combobox
private void CargarAlumnos()
{
cbxalumnos.DataSource = AlumnoBL.CargarAlumnos();
cbxalumnos.ValueMember = "AluId";
cbxalumnos.DisplayMember = "AluNombre";
}

private void FrmAlumno_Load(object sender, EventArgs e)
{
CargarAlumnos();

//cargo materias en combobox
cbxmaterias.DataSource = MateriaBL.CargarMaterias();
cbxmaterias.ValueMember = "MatId";
cbxmaterias.DisplayMember = "MatNombre";

}

Tenemos un mtodo CargarAlumnos() que lo que hace es cargos el nombre de todos los alumnos en un combobox este
mtodo lo llamaremos luego de actualizar o agregar un nuevo alumno para que los datos del combobox se actualicen y en el
evento load del formulario tambin cargamos todas las materias en otro combobox.
Agregar o Actualizar Alumno.
//Variable global que prepresenta al alumno seleccionado
Alumno alum = null;

private void btnguardar_Click(object sender, EventArgs e)
{
//compruebo las validaciones
if (!ValidacionesAlumno())
return;
18


// si el cliente se ha seleccionado lo actualizo, sino se crea uno nuevo
if(alum == null)
alum = new Alumno();

alum.AluNombre = txtnombre.Text;
alum.AluApellido = txtapellido.Text;
alum.AluEdad = Convert.ToInt16(txtedad.Text);
alum.AluDireccion = txtdireccion.Text;

alum = AlumnoBL.Save(alum);
MessageBox.Show("Se agrego o Actulizo el Alumno con Id:" +alum.AluId);
CargarAlumnos();
Limpiar();
}

Tenemos una variable global que representa un alumno, luego la capa de negocio validad si la entidad(Alumno) existe o no
por medio del id y en base a esto se ejecuta la operacin correspondiente a cada caso, tambin en el cdigo encontramos
los mtodosValidacionesAlumno() que lo que hace es validar que los datos de la entidad Alumno sean los
correctos, CargarAlumnos() luego de agregar o actualizar un alumno vuelve a cargar los alumnos y Limpiar() que limpia los
datos de los textbox.
Agregar Nota.
private void btnguardarnota_Click(object sender, EventArgs e)
{
//compruebo las validaciones
if (!ValidacionesNotas())
return;

//creo una nota nueva
Nota not = new Nota();
not.AluId = Convert.ToInt32(cbxalumnos.SelectedValue);
not.MatId = Convert.ToInt32(cbxmaterias.SelectedValue);
not.NotNota = Convert.ToDecimal(txtnota.Text);

//si nota para la materia no existe se crea si no muestra mensaje que ya existe
if (!NotaBL.CreateNota(not))
{
MessageBox.Show("Se agrego la Nota con Id:" + not.NotId);
Limpiar();
}
else
MessageBox.Show("Ya Existe una Nota del Alumno para la Materia:" + cbxmaterias.Text);
}

La capa de negocio se encarga de validar si ya existe una nota para una materia de un alumno si no existe la agrega y si
existe muestra un mensaje que ya existe una nota para la materia, dentro del codigo encontramos los
metodos ValidacionesNotas() que lo que hace que los datos para agregar una nota sean correctos y Limpiar() limpia los
datos de los textbox.

Editar Notas.
//variable global de entidad nota
Nota not = new Nota();

private void btnguardar_Click(object sender, EventArgs e)
{
//compruebo validaciones
19

if (!ValidacionesNota())
return;

not.NotId = Convert.ToInt32(txtidnota.Text);
not.AluId = Convert.ToInt32(txtidalumno.Text);
not.MatId = Convert.ToInt32(txtidmateria.Text);
not.NotNota = Convert.ToDecimal(txtnota.Text);

//si nota existe la actualizo
if (NotaBL.UpdateNota(not))
{
MessageBox.Show("Se actualizo la nota con Id:" + not.NotId);
CargarGrilla();
Limpiar();
}
else
MessageBox.Show("No se pudo actualizar la nota");
}

La capa de negocio se encarga de validar si la nota existe por medio del id, si existe actualiza el registro si no muestra
mensaje que no se puede actualizar, en el cdigo encontramos los mtodos ValidacionesNota() valida que los datos para
agregar una nota sean correctos,CargarGrilla() carga todas las notas de un alumno en un datagridview y Limpiar() limpia los
datos de los textbox.



Conclusin
A lo largo de los 4 artculos hemos visto como desarrollar un proyecto en capas en .net usando entity framework, si bien el
ejemplo puede ser un poco sencillo pero puede servir de gua o ejemplo para nuestros futuros desarrollos.

You might also like