Archivo de la etiqueta: Entity Framework 6

Entity Framework 6 operaciones CRUD

 

Entity Framework es un potente ORM creado por Microsoft que facilita el trabajo del mapeo a las entidades y facilita la implementación de la capa de datos usando Linq to Entities. Entity Framework tiene varios enfoques como, Code First, Model First, Database First.

Code First, es un enfoque mas de Entity Framework que permite crear una base de datos a partir de código(C#, VB.NET), por defecto se utiliza el nombre de nuestras clases y correspondientes propiedades para crear nombres de tablas y campos.

Model First, le da la posibilidad de diseñar toda la lógica del negocio, le permite crear un modelo nuevo mediante Entity Framework Designer y después genera un esquema de la base de datos a partir del modelo.

Database First, el modelo conceptual se crea a partir de una base de datos existente, el cual se almacena en una archivo .edmx y este se podrá ver y editar en un diseñador, para actualizar nuevos cambios que surjan en nuestra base de datos.

En esta ocasión voy a usar DataBase First pero antes se debe crear una base de datos de prueba.

CREATE DATABASE PruebaEF
GO
USE PruebaEF
GO
CREATE TABLE [dbo].[Personal](
 [Id] [varchar](6) NOT NULL,
 [Nombre] [varchar](80) NULL,
 [Direccion] [varchar](100) NULL,
 [Telefono] [varchar](9) NULL,
 [lEstado] [smallint] NULL,
 CONSTRAINT [PK_Personal] PRIMARY KEY CLUSTERED
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

Para este ejemplo estoy usando Visual Studio 2013 y SQL 2014.

Una vez teniendo la base de datos creada pasamos a crear una solución distribuida en una arquitectura de 3 capas, Presentación(Proyecto Windows Forms),  Dominio(Proyecto Class Library), Persistencia Datos(Proyecto Class Library), se hace las referencia entre capas Persistencia en Dominio, Persistencia y Dominio en Presentación, referencio Persistencia en Presentación por que el mapeo a la infraestructura de la DB esta en esa capa solo por eso, pero la lógica de la aplicación va en el Dominio.

Se instala en la capa de Persistencia y Presentación Entity Framework desde Nuguet, hecho eso se agrega un nuevo elemento desde el proyecto de Persistencia, ADO.NET Entity Data Model.

entity data model

Ahora nos conectamos a la base de datos para obtener el modelo.

conectando a la db

Seleccionamos las tablas que se requieren para el modelo.

escojer las tablas

Escogemos el Framework a trabajar en mi caso lo dejo como esta.

escoger el EF

Obtenemos el modelo.

modelo

Y también tenemos el mapping de la infraestuctura de la DB.

//------------------------------------------------------------------------------
// <auto-generated>
// Este código se generó a partir de una plantilla.
//
// Los cambios manuales en este archivo pueden causar un comportamiento inesperado de la aplicación.
// Los cambios manuales en este archivo se sobrescribirán si se regenera el código.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Prueba.PersistenciaDatos.Modelo
{
 using System;
 using System.Collections.Generic;

 public partial class Personal
 {
 public string Id { get; set; }
 public string Nombre { get; set; }
 public string Direccion { get; set; }
 public string Telefono { get; set; }
 public Nullable<short> lEstado { get; set; }
 }
}

Ya podemos comenzar a trabajar comenzando con la implementación vamos a ubicar el context que es el que se conecta a la base de datos para poder persistir contra ella.

context

Esto se encuentra ubicado en el Model1.Context, voy a implementar la capa de persistencia usando linq to entities, me olvidaba agregar la referencia System.Data.Entity

using Prueba.PersistenciaDatos.Modelo;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Prueba.PersistenciaDatos
{
 public class PersonalRepository
 {

 public List<ModeloMinimo.PersonalMinimalModel> GetPersonal()
 {
 using(var context = new PruebaEFEntities())
 {
 return (from p in context.Personal
 select new ModeloMinimo.PersonalMinimalModel
 {
 Id = p.Id,
 Nombre = p.Nombre
 }).ToList();
 }
 }

 public string GenerarCodigo()
 {
 using(var context = new PruebaEFEntities())
 {
 int codigo;
 var ultimoId = Convert.ToInt32(context.Personal.Max(x => x.Id)) + Convert.ToInt32(1);
 codigo = ultimoId;
 return string.Format("{0:000000}", codigo);
 }
 }

 public bool Existe(string codigo)
 {
 using(var context = new PruebaEFEntities())
 {
 int resultado = context.Personal.Where(x => x.Id == codigo).Count();
 if (resultado == 0)
 return false;
 else
 return true;
 }
 }
 public Personal Buscar(string codigo)
 {
 using(var context = new PruebaEFEntities())
 {
 var strSQL = from p in context.Personal
 where p.Id == codigo
 select p;
 return strSQL.First();
 }
 }

 public void Guardar(Personal model)
 {
 try
 {
 using(var context = new PruebaEFEntities())
 {
 context.Personal.Add(model);
 context.SaveChanges();
 }
 }
 catch (Exception ex)
 {
 throw new Exception("No se puede guardar el registro", ex);
 }
 }

 public void Actualizar(Personal model)
 {
 try
 {
 using(var context = new PruebaEFEntities())
 {
 context.Entry(model).State = EntityState.Modified;
 context.SaveChanges();
 }
 }
 catch (Exception ex)
 {
 throw new Exception("No se puede actualizar el registro", ex);
 }
 }

 public void Eliminar(string codigo)
 {
 using(var context = new PruebaEFEntities())
 {
 var entities = (from p in context.Personal
 where p.Id == codigo
 select p).Single();
 context.Personal.Remove(entities);
 context.SaveChanges();
 }

 }

 }
}

Implementando el dominio en el cual uso una técnica para desacoplar la capa de Presentación con la capa de Dominio.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prueba.PersistenciaDatos;
using System.Linq.Expressions;

namespace Prueba.Dominio
{
 public class Personal
 {
 public string MensajeLogica;
 public string MensajeError;

 PersonalRepository personal = new PersonalRepository();

 public List<PersistenciaDatos.ModeloMinimo.PersonalMinimalModel> GetPersonal()
 {
 return personal.GetPersonal();
 }

 public PersistenciaDatos.Modelo.Personal Buscar(string codigo)
 {
 return personal.Buscar(codigo);
 }

 public void Guardar(PersistenciaDatos.Modelo.Personal model)
 {
 BusinessException.Clear();
 if (string.IsNullOrEmpty(model.Nombre)) BusinessException.Add("Debe ingresar el nombre");

 if(BusinessException.Count() == 0)
 {
 if(string.IsNullOrEmpty(model.Id))
 model.Id = personal.GenerarCodigo();

 try
 {
 if(personal.Existe(model.Id))
 {
 personal.Actualizar(model);
 MensajeLogica = "Registro actualizado";
 }
 else
 {
 personal.Guardar(model);
 MensajeLogica = "Registro guardado";
 }
 }
 catch (Exception ex)
 {
 BusinessException.Add(ex.Message);
 }

 }
 }

 public void Eliminar(string codigo)
 {
 personal.Eliminar(codigo);
 }

 }
}

Implementando la capa de Presentación, se debe copiar el app.config de la capa de Persistencia a la Presentación.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Prueba.PersistenciaDatos;
using Prueba.Dominio;

namespace Prueba.WindowsUI
{
 public partial class frmPersonal : Form
 {
 private string strCodigo;

 Dominio.Personal personal = new Dominio.Personal();

 public frmPersonal()
 {
 InitializeComponent();
 }

 private void frmPersonal_Load(object sender, EventArgs e)
 {
 LoadDGVPersonal();

 }

 private void btnGuardar_Click(object sender, EventArgs e)
 {
 PersistenciaDatos.Modelo.Personal model = new PersistenciaDatos.Modelo.Personal();
 model.Id = lblCodigo.Text;
 model.Nombre = txtNombre.Text;
 model.Direccion = txtDireccion.Text;
 model.Telefono = txtTelefono.Text;
 model.lEstado = Convert.ToInt16(chkEstado.Checked ? "1" : "0");
 personal.Guardar(model);
 LoadDGVPersonal();
 }

 void LoadDGVPersonal()
 {
 List<PersistenciaDatos.ModeloMinimo.PersonalMinimalModel> list = personal.GetPersonal();
 dgvPersonal.AutoGenerateColumns = false;
 dgvPersonal.DataSource = list;
 }

 void ObtenerId()
 {
 strCodigo = Convert.ToString(dgvPersonal.CurrentRow.Cells[0].Value);
 }

 void Buscar()
 {
 if(strCodigo != string.Empty)
 {
 PersistenciaDatos.Modelo.Personal model = personal.Buscar(strCodigo);
 lblCodigo.Text = model.Id;
 txtNombre.Text = model.Nombre;
 txtDireccion.Text = model.Direccion;
 txtTelefono.Text = model.Telefono;
 chkEstado.Checked = Convert.ToBoolean(model.lEstado);
 }
 }

 void Eliminar()
 {
 ObtenerId();
 string msg = string.Format("Se va a ELIMINAR el registro: {0} {1} {0} Código: {2} {0} Nombre: {3}",
 Environment.NewLine,
 new string('-', 50), dgvPersonal.CurrentRow.Cells[0].Value,
 dgvPersonal.CurrentRow.Cells[1].Value);

 if (MessageBox.Show(msg, "Personal", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
 {
 personal.Eliminar(strCodigo);
 LoadDGVPersonal();
 }
 }

 private void dgvPersonal_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
 {
 ObtenerId();
 Buscar();
 tabControl1.SelectedTab = tabPage2;
 }

 private void frmPersonal_KeyDown(object sender, KeyEventArgs e)
 {
 if(e.KeyCode == Keys.F7)
 {
 Eliminar();
 }
 }

 }
}

Al ejecutar la aplicación queda de esta manera.

frmPersonal datos

lista

Adjunto el proyecto para que lo puedan descargar, el próximo post será Inversión de Control IoC con Ninject.

Proyecto C#