Tag Archives: desarrollo

SignalR Hub

19 Jun

¿Qué es SignalR Hub?

Simplemente, con lo simple que puede ser, SignalR Hub, son un conjunto de librerías que permiten invocar desde javascript al servidor, y lo que es realmente importante, permite al servidor ejecutar funcionalidad javascript, evitando recarga de página, ejecutando la función javascript de todos los clientes.

Uso de SignalR Hub

¿Para qué podemos usar SignalR hub?, el ejemplo que va a encontrar en internet es el típico chat, aunque desde este punto se puede evolucionar a listas de espera con registro en base de datos de la información que requiera la aplicación.

Registro de librerías

Lo recomendable es instalar las librerías necesarias para implementar la solución desde el Administrador de Paquete Nuget, ya que el paquete que descargue estará configurado para su entorno.

Librerías para el uso de SignalR Hub

Desde el administrador de Paquetes Nuget descargue:

  • Microsoft.AspNet.SignalR.Core.dll
  • Microsoft.AspNet.SignalR.SystemWeb.dll
  • Microsoft.Orwin.dll
  • Microsoft.Orwin.Host.SystemWeb.dll
  • Microsoft.Orwin.Security.dll
  • Newtonsoft.Json.dll
  • Owin.dll

Javascript

La descarga de los paquetes anteriores, incluye una serie de ficheros javascript “.js” que habrá que incluir en las páginas en las que queremos implementar las listas de espera o el chat.

Los ficheros .js son:

  • jquery-1.6.4.min.js
  • jquery.signalR-2.2.1.min.js
  • hubs

Dependiendo de la versión descargada por el administrador de paquetes Nuget la numeración de las versiones puede variar.

Si  no esta acostumbrado a trabajar con javascript le diré que el orden es muy importante, así que incluya los ficheros .js en el orden indicado para evitar errores.

Mesa

Como he comentado antes lo bueno de SignalrR Hub es la capacidad de comunicar cliente con servidor y servidor con clientes,

¿Cómo se hace?

Código de la mesa1

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Mesa1.aspx.cs” Inherits=”Mesa1″ %>

<!DOCTYPE html>

<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head runat=”server”>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title></title>
http://Scripts/jquery-1.6.4.min.js
http://Scripts/jquery.signalR-2.2.1.min.js
http://signalr/hubs

//Funciones para que el servidor conecte con el cliente
$(function () {
var turno = $.connection.turno;

//Método por el que contacta el servidor.
$.connection.hub.start().done(function () {

//ejecuta primero el javascript, con lo que el visitante no se ha establecido.
$(“#btnSiguiente”).click(function () { turno.server.siguiente(1); });

// Actualiza la lista de espera
$(“#btnActualiza”).click(function () { turno.server.cargaListaEspera(1); });
});

})

</head>
<body>
<form id=”form1″ runat=”server”>

Atendiendo a:

Observaciones:

</form>
</body>
</html>

Con esto ya tendríamos la primera mesa que atendería la lista de espera.

Registro de visitas

Creamos un aspx 

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Inscribir.aspx.cs” Inherits=”Inscribir” %>

<!DOCTYPE html>

<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head runat=”server”>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Registro de visitas.</title>
http://Scripts/jquery-1.6.4.min.js
http://Scripts/jquery.signalR-2.2.1.min.js
http://signalr/hubs

$(function () {

var turno = $.connection.turno;

//Invocacíon al servidor.
$.connection.hub.start().done(function () {
$(“#usuario”).val(“”);

$(“#sendButton”).click(function () {

turno.server.inscribir($(“#ddlAsunto”).val() + “@” + $(“#usuario”).val());

$(“#usuario”).val(“”);
});
});
});

</head>
<body>
<form id=”form1″ runat=”server”>

Registro de visitas
Visita

Haga click con el ratón en la caja y escriba el nombre con el que será llamado para ser atendido.


Asunto




Seleccione el asunto a tratar.
Inscribirse

<textarea id=”lista1″ style=”visibility: hidden;”></textarea>
<textarea id=”lista2″ style=”visibility: hidden;”></textarea>
<textarea id=”lista3″ style=”visibility: hidden;”></textarea>

</form>
</body>
</html>

CodeBehind del registro de visitas

En el load de la página cargamos el dropDownList con los asuntos que se tratan en las mesas.

Pantalla de Turnos

<!DOCTYPE html>

<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Turno</title>
http://Scripts/jquery-1.6.4.min.js
http://Scripts/jquery.signalR-2.2.1.min.js
http://signalr/hubs

function CargarLista(lista) {
var listaCargada = “”;

// El primero no se coge ya que pasa a Atendido
for (var i = 0; i
</head>
<body>
<form id=”form1″>
<input type=”button” id=”test” />
<table border=”0″ cellpadding=”5″ cellspacing=”0″>
<tr>
<td width=”20%”><h1>Mesa 1:</h1></td>
<td width=”20%”><h1>Mesa 2:</h1></td>
<td width=”20%”><h1>Mesa 3:</h1></td>
<td width=”40%”><h1>Su Turno</h1></td>
</tr>
<tr>
<td valign=”top”><input type=”text” id=”Mesa1Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;”/></td>
<td valign=”top”><input type=”text” id=”Mesa2Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;”/></td>
<td valign=”top”><input type=”text” id=”Mesa3Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;”/></td>
<td valign=”top” rowspan=”5″><textarea id=”lista” style=”font-size:large; width:100%; height:650px;”></textarea></td>
</tr>
<tr>
<td width=”20%”><h1>Mesa 4:</h1></td>
<td width=”20%”><h1>Mesa 5:</h1></td>
<td width=”20%”><h1>Mesa 6:</h1></td>
</tr>
<tr>
<td valign=”top”><input type=”text” id=”Mesa4Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;” /></td>
<td valign=”top”><input type=”text” id=”Mesa5Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;” /></td>
<td valign=”top”><input type=”text” id=”Mesa6Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;” /></td>
</tr>
<tr>
<td><h1>Mesa 7:</h1></td>
<td><h1>Mesa 8:</h1></td>
<td><h1></h1></td>
</tr>
<tr>
<td valign=”top”><input type=”text” id=”Mesa7Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;”/></td>
<td valign=”top”><input type=”text” id=”Mesa8Usuario” style=”font-family:Arial, Helvetica, sans-serif; font-size:x-large; color: orange; border-width:0;”/></td>
<td></td>
</tr>
</table><br />
<footer style=”font-size:xx-small;”>Informática El Tesoro, desarrollado por Grupo I.C.A.</footer>
</form>
</body>
</html>

Entidades indispensables

Necesitaremos dos:

Startup.cs

using Microsoft.Owin;
using Owin;

//[assembly: OwinStartup(typeof(Startup))]
[assembly: OwinStartup(typeof(SignalRHub.Startup))]

namespace SignalRHub
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}

La entidad que contiene los métodos a invocar desde el cliente

using System;
using System.Collections.Generic;
using Microsoft.AspNet.SignalR;
using Turnos.Entidades;
using Turnos.BL;
using Turnos.Tipos;

namespace SignalRHub
{

public class Turno : Hub
{

public void cargaListaEspera(Int16 idMesaAsunto)
{
obtenerLista(idMesaAsunto, Tipos.Origen.Actualiza);
}

/// <summary>
/// Registra en BBDD el nuevo visitante
/// </summary>
/// <param name=”cadena”></param>
public void inscribir(string cadena)
{
// volcamos valores de mesa y visitante en una entidad Turno
Visita nuevo = new Visita();
nuevo.IdAsunto = short.Parse(cadena.Split(‘@’)[0]);
nuevo.Visitante = cadena.Split(‘@’)[1];
// añadimos la hora de inscripcion – entrada
nuevo.HoraEntrada = System.DateTime.Now;
// registramos datos
VisitaControlador.Insertar(nuevo);
// Actualizamos la lista de espera de turnos.
actualizaListaTurnos();
}

/// <summary>
/// Recarga la lista de espera.
/// </summary>
public void siguiente(Int16 idMesa)
{
Visita siguiente = VisitaControlador.ObtenerSiguiente(idMesa);

// Devolvemos la lista
obtenerLista(idMesa, Tipos.Origen.Siguiente);
}

 

/// <summary>
/// Actualiza la lista de espera de turnos.
/// </summary>
public void actualizaListaTurnos()
{
List<Visita> lista = VisitaControlador.ObtenerListaEspera();

string ListaMontada = string.Empty;

bool primero = true;
string separador = string.Empty;
foreach (Visita item in lista)
{
if (!primero)
{
separador = “#”;
}

List<Mesa> Mesas = MesaAsuntoControlador.Obtener_Mesas(item.IdAsunto);

string strMesa = string.Empty;
foreach (Mesa itemMesa in Mesas)
{
strMesa += itemMesa.Denominacion + ” “;
}

if (string.IsNullOrEmpty(separador))
{
ListaMontada = item.Id + ‘@’.ToString() + item.Visitante + ” => ” + strMesa;
}
else
{
ListaMontada += separador + item.Id + ‘@’.ToString() + item.Visitante + ” => ” + strMesa;
}
primero = false;
}

Clients.All.ActualizaListaTurnos(ListaMontada);
}

/// <summary>
/// Obtiene la lista de espera de la mesa recibida por parámetro.
/// </summary>
/// <param name=”idMesaAsunto”></param>
private void obtenerLista(Int16 idMesa, Tipos.Origen origen)
{

//Tipos.Origen accionOrigen = Tipos.ConversorIntOrigen(origen);
Tipos.Origen accionOrigen = origen;

// actualizamos la lista de mesas
List<Visita> lista = VisitaControlador.ObtenerListaEspera(idMesa);
// montamos cadena con el id y el visitante, para devolver como cadena.
var listaEnvio = MontarCadena(lista);
// actualizamos la lista genérica
List<Visita> listaGenerica = VisitaControlador.ObtenerListaEspera();
// montamos cadena con el id y el visitante, para devolver como cadena.
var listaCompleta = MontarCadena(listaGenerica);

// Actualizamos la lista genérica: En Turno.html llamar al siguiente.
Clients.All.ActualizaListaTurnos(listaCompleta);

// enviamos la lista de espera completa para la mesa.
switch (idMesa)
{
case 1:
switch (accionOrigen)
{

case Tipos.Origen.Siguiente: // Pulsado botón Siguiente.
// Actualizamos la lista de espera de la mesa 1: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa1Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}

break;
case 2:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 2: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa2Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}

break;
case 3:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa3Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
case 4:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa4Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
case 5:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa5Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
case 6:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa6Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
case 7:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa7Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
case 8:
switch (accionOrigen)
{
case Tipos.Origen.Siguiente: // Pulsado botón Siguiente,
// Actualizamos la lista de espera de la mesa 3: En Turno.html.
Visita actual = VisitaControlador.ObtenerAtendido(idMesa);
Clients.All.TurnoMesa8Siguiente(actual.Id.ToString() + ‘@’ + actual.Visitante);
break;
case Tipos.Origen.Actualiza: // Actualiza lista de espera en la mesa.
Clients.All.ActualizaListaEspera(listaEnvio);
break;
}
break;
default:
break;
}
}

 

/// <summary>

/// Monta la cadena a enviar a cliente con el Id, visistante y mesas.
/// </summary>
/// <param name=”lista”></param>
/// <returns></returns>
private string MontarCadena(System.Collections.Generic.List<Visita> lista)
{
string ListaMontada = string.Empty;

bool primero = true;
string separador = string.Empty;
foreach (Visita item in lista)
{
if (!primero)
{
separador = “#”;
}

List<Mesa> Mesas = MesaAsuntoControlador.Obtener_Mesas(item.IdAsunto);

string strMesa = string.Empty;
foreach (Mesa itemMesa in Mesas)
{
strMesa += itemMesa.Denominacion + ” “;
}

if (string.IsNullOrEmpty(separador))
{
ListaMontada = item.Id + ‘@’.ToString() + item.Visitante + ” => ” + strMesa;
}
else
{
ListaMontada += separador + item.Id + ‘@’.ToString() + item.Visitante + ” => ” + strMesa;
}
primero = false;
}
return ListaMontada;
}

}
}

 

Anuncios

Cómo implementar multiidioma en 5 pasos

24 Jun

Antes de conocer como funcionaba el multiidioma de un navegador, no es que ahora lo conozca en profundidad pero ya hemos roto el hielo, creía que se definía una vez, que lo mismo se puede, y te olvidabas. Tras investigar sobre el tema, la manera más utilizada, hay que recargarla en cada “Response”, así que comparto aquí cómo lo he implementado, espero que te sirva.

Pruebas realizadas con Microsoft Visual Studio Express 2013 for web, C#.

Sigue leyendo

C#, ¿qué ? y ¿cómo ?

2 Mar

Tras unos días ampliando mi zona de confort, que se lleva mucho ahora, con C# y la modificación de archivos pdf, recibidos como array de byte, he dejado para el recuerdo una serie de artículos que a lo mejor os sirven como orientación:

  • ¿Cómo convertir array de Byte en MemoryStream?
  • ¿Cómo recuperar un certificado con X509Certificates?
  • ¿Cómo incluir texto en un array de byte(pdf)?
  • ¿Cómo recuperar un certificado con X509Certificates?

    26 Feb

    Los certificados son archivos que nos ayudan a proteger un fichero y evitar así que puedan ser modificados por terceras personas o máquinas que puedan suplantarnos.

    En este ejemplo intento mostrar como recuperar un certificado de una colección o almacén de certificados y firmar un array de byte.

    Requisitos X509Certificates y iTextSharp.
    Sigue leyendo

    ¿Qué es y cómo usar un fichero de recursos?

    3 Feb

    En este artículo, que os aviso está basado en notas y puede que no quede tan claro como otros, veremos cómo crear, mantener y consumir un fichero de recursos.

    ¿Qué es un fichero de recursos?
    Los ficheros de recursos, son los archivos que no contienen código fuente, los datos de estos recursos se almacenan en formato xml y son constantes, valores fijos para toda la aplicación.
    Nos centramos en el uso de los recursos para la traducción de nuestra aplicación en diversos idiomas.
    Al distribuir la aplicación ha de incluir el ensamblado de la aplicación principal y el de los satélites o ficheros de recursos, nuevos o modificados. Cuando modifique un fichero de recursos, no será necesario volver a compilar el ensamblado de la aplicación principal.

    Creación de un fichero de recursos
    La creación de un fichero de recursos es tan sencilla como pulsar el botón derecho sobre la carpeta App_GlobalResources, añadir nuevo elemento y suministrar los valores necesarios a la ventana que aparecerá…

    Asignar un nombre y aceptar.

    Cargar datos en un fichero de recursos
    Una vez creado el fichero, podemos acceder a él, como siempre, haciendo doble click sobre él y se abrirá el fichero con un formato de tabla.

    Para añadir datos es tan sencillo como ir rellenando los datos:
    • Columna nombre: Identificador por el que se referencia el recurso.
    • Columna valor: Texto que mostrará cuando usemos el recurso.
    • Columna comentario: Comentario sobre su uso.

    Consultar el fichero de recursos
    Para poder utilizar el fichero de recursos creado en el apartado anterior, se puede hacer de dos maneras:
    i. Incluir en la página Code Behind (aspx.vb) la instrucción Imports Resources.
    ii. Sin incluir ningún imports.
    Dependiendo de si hemos declarado el uso del fichero Resources o no, tendremos que buscar los recursos de las siguientes formas para cargar nuestra variable de texto TxtMensaje:
    TxtMensaje = Resource.msg_NoSeHaEncontrado
    TxtMensaje = Resources.Resource.msg_NoSeHaEncontrado
    Incluyendo un manejador
    Dim rm As ResourceManager
    rm = ResourceManager.CreateFileBasedResourceManager(“strings”,”.”,Nothing)

    Ejemplo Asignación de los recursos(dependiendo de idioma)
    Para poder tener nuestra aplicación en varios idiomas, declaramos un fichero de recursos por cada idioma.

    Una vez declarados los ficheros de recursos, habría que declararse una variable en la que almacenar en que idioma mostrar la información, al ser una información dependiente de cada usuario, lo suyo sería declarar una variable de visible para toda la aplicación en la que almacenaríamos la opción elegida por el usuario.

    Hay varias maneras de mostrar los mensajes.
    1) Ejemplo, aunque he definido K y le he asigando un valor fijo, se podría sustituir, por el valor que este usuario tiene guardado en base de datos, o dependiendo de dónde se accede, o del que ha seleccionado en un combo en la web.

    Dim k As String = “ESPAÑOL”

    2) Ejemplo, dependiendo del valor de k, iremos a recuperar el valor que nos interesa, a modo de ejemplo.
    If k = “ESPAÑOL” Then
    CargarMensaje(Resources.SP.saludo)
    Else
    CargarMensaje(Resources.EN.saludo)
    End If

    Infragistics Toolbar, o como codificar un menú en 2 pasitos

    24 Dic

    Infragistics es una empresa dedicada entre otras cosas a generar controles ASP.NET avanzados que permiten crear de forma rápida experiencias de usuario superiores de estilo, con la estabilidad y el rendimiento necesarios para confiar en ellos a la hora de desarrollar.

    Uno de estos controles es el ToolBar o barra de menú, una vez instalado el control e insertado en nuestro formulario, hay que cargarlo en modo diseño, por ejemplo, aunque también se puede cargar por código pero eso lo dejo para otra entrada.
    Para la definición de las opciones del menú utilizaremos la opción del menú contextual del control seleccionando ActiveX Configure

    menu

    Paso 1 Cofiguración
    Al seleccionar la opción se nos abrirán dos pantallas, una con “como queda el menú” y otra con la definición de las diferentes secciones.
    menuConfig

    En la ventana “Configuration Control Panel” podemos crear nuevas opciones de nuestro menú con el botón New o editar las existentes con Edit es bastante sencillo, sólo hay que tener cuidado con el tipo de entrada. Button si es una opción de menú que nos abrirá un formulario o Menu si es una opción de menú que nos abrirá un submenú.

    Según se vayan declarando las opciones o una vez que tengamos todas creadas, eso da igual, hay que añadirlas al diseño del menú, en el orden y dentro del submenú en el que queramos que se muestren. Para esto no se necesita nada mas que seleccionar de la lista de elementos y arrastrarlo a la posición elegida en el menú. No pasa nada si no aciertas con el orden, lo puedes modificar tantas veces como quieras en diseño.

    Bien, supongamos que ya hemos introducido nuestro menú con sus sesenta elementos. Ahora en el código tendremos que ver que id nos han pulsado para poder definir la instrucción a realizar, y aquí está la finalidad de este artículo…
    ¿Vamos a escribirnos un “select” con las distintas opciones?, si lo hacemos así vamos a perder mucho tiempo y nos arriesgamos a que al ejecutar el id escrito a mano no concuerde con el escrito en la configuración.

    Fijaos en este primer plano de la imagen dos.
    MenuOpciones

    Paso 2 Exportar Id del menú
    Pulsando sobre la opción remarcada Copy Tools IDs To Clipboard AS VB ‘Select’ Stament, no necesita traducción, pero Copia los ID de las opciones como una sentencia ‘Select’ de VB. Sólo nos queda pegarlo en el evento ToolClick de nuestro menú.

    Espero que con este ejemplo pueda recordar como configurar y exportar los ID de un menú en el futuro y os sirva a vosotros…

    Sean felices desarrollando y feliz Navidad.

    LinQ – consultas

    26 Nov

    LINQ o Language Integrated Query es un conjunto herramientas de Microsoft para realizar todo tipo de consultas a distintas fuentes de datos: objetos, xmls, bases de datos, etc… Para ello, usa un tipo de funciones propias, que unifica las operaciones más comunes en todos los entornos, con esto, se consigue un mismo lenguaje para todo tipo de tareas con datos.

    En este artículo voy a dejar un ejemplo de cómo utilizar este tipo de consultas, que aunque es un poco lioso al principio se puede llegar a entender.

    Aunque no es necesario, es mejor tener alguna noción de SQL, pero no es imprescindible.

    A estas alturas, todos sabemos lo que es una clase y como se usa, para este ejemplo vamos a trabajar con una clase ENAcuerdo, definida a continuación

    Imports System

    Imports System.Collections.Generic

    Imports System.Text

    Namespace EntidadesNegocio.Administracion

    ”’ <summary>

    ”’ EDAcuerdo  – Acuerdos para procuradores.

    ”’ </summary>

    ”’ <remarks></remarks>

    <Serializable()> _

    Partial Public Class ENAcuerdo

    Public Sub New()

    MyBase.New()

    End Sub

    Private m_Pk As Nullable(Of Integer)

    Private m_Fechainicio As Nullable(Of Date)

    Private m_Fechafin As Nullable(Of Date)

    ”’ <summary>

    ”’ Identificador único del acuerdo.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Pk() As Nullable(Of Integer)

    Get

    Return m_Pk

    End Get

    Set(ByVal value As Nullable(Of Integer))

    m_Pk = value

    End Set

    End Property

    ”’ <summary>

    ”’ Fecha de entrada en vigencia del acuerdo.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Fechainicio() As Nullable(Of Date)

    Get

    Return m_Fechainicio

    End Get

    Set(ByVal value As Nullable(Of Date))

    m_Fechainicio = value

    End Set

    End Property

    ”’ <summary>

    ”’ Fecha de fin de vigencia del acuerdo.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Fechafin() As Nullable(Of Date)

    Get

    Return m_Fechafin

    End Get

    Set(ByVal value As Nullable(Of Date))

    m_Fechafin = value

    End Set

    End Property

    End Class

    End Namespace

    Recordamos que las clases deben estar organizadas en espacios de nombres para que sea más fácil su localización y tener una idea de para que son.

    Linq lo utilizamos para consultas, así que necesitamos una colección que contenga más de una entidad…

    Namespace ColeccionesNegocio.Administracion

    ”’ <summary>

    ”’ Colección negocio ENAcuerdo – Acuerdos para procuradores.

    ”’ </summary>

    ”’ <remarks></remarks>

    Public Class CNAcuerdo

    Inherits System.Collections.CollectionBase

    Implements ICollection(Of

    EntidadesNegocio.Administracion.ENAcuerdo)

    Public Function ToList() As List(Of

    EntidadesNegocio.Administracion.ENAcuerdo)

    Return List.Cast(Of

    EntidadesNegocio.Administracion.ENAcuerdo).ToList

    End Function

    Public Function Item(ByVal index As Integer) As

    EntidadesNegocio.Administracion.ENAcuerdo

    Return List.Item(index)

    End Function

    Public Sub Add(ByVal item As EntidadesNegocio.Administracion.ENAcuerdo) Implements System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).Add

    List.Add(item)

    End Sub

    Shadows Sub Clear1() Implements System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).Clear

    List.Clear()

    End Sub

    Public Function Contains(ByVal item As EntidadesNegocio.Administracion.ENAcuerdo) As Boolean Implements

    System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).Contains

    Return List.Contains(item)

    End Function

    Public Sub CopyTo(ByVal array() As EntidadesNegocio.Administracion.ENAcuerdo, ByVal arrayIndex As

    Integer) Implements System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).CopyTo

    List.CopyTo(array, arrayIndex)

    End Sub

    Shadows ReadOnly Property Count1() As Integer Implements System.Collections.Generic.ICollection(Of

    EntidadesNegocio.Administracion.ENAcuerdo).Count

    Get

    Return List.Count

    End Get

    End Property

    Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).IsReadOnly

    Get

    Return List.IsReadOnly

    End Get

    End Property

    Public Function Remove(ByVal item As EntidadesNegocio.Administracion.ENAcuerdo) As Boolean Implements

    System.Collections.Generic.ICollection(Of EntidadesNegocio.Administracion.ENAcuerdo).Remove

    If List.Contains(item) Then

    List.Remove(item)

    Return True

    Else

    Return False

    End If

    End Function

    Shadows Function GetEnumerator1() As System.Collections.Generic.IEnumerator(Of EntidadesNegocio.Administracion.ENAcuerdo) Implements System.Collections.Generic.IEnumerable(Of EntidadesNegocio.Administracion.ENAcuerdo).GetEnumerator

    Return List.GetEnumerator

    End Function

    End Class

    End Namespace

    Ya tenemos una colección, ahora hagamos un ejemplo sencillo de los de internet.

    Supongamos que queremos recuperar los acuerdos en que la fecha de inicio sea mayor a hoy, para ello en lugar de filtar la colección mediante su operación de negocio y creación y carga de filtro, utilizamos linq.

    Dim lista = (From acuerdo As GRMMapper.EntidadesNegocio.Administracion.ENAcuerdo _

    In colAcuerdos.ToList _

    Where  (acuerdo.Fechainicio >= now) _

    Select acuerdo)

    Nos creamos una variable en la que almacenaremos los datos obtenidos de la consulta.

    Importante, a mí me pasa a menudo, no olvidar convertir la colección a una lista (colAcuerdos.ToList)

    Recorremos la colección de acuerdos, convertida en lista, de acuerdo en acuerdo.

    Where, cláusula como en sql con la condición,

    Y el dato a recuperar, Select acuerdo, podríamos sólo haber recuperado la fechafin, poniendo

    acuerdo.Fechafin

    En lista, tendríamos almacenado una colección de acuerdos filtrados en una sola línea.

    Hasta aquí fácil, ahora un ejemplo de una INNER JOIN este más complicado de encontrar por internet.

    Imaginemos que tenemos otra entidad en la que relacionamos los acuerdos con los procuradores que los firman cada año.

    Imports System

    Imports System.Collections.Generic

    Imports System.Text

    Namespace EntidadesNegocio.Administracion

    ”’ <summary>

    ”’ EDAcuerdoprocurador  – Relación de Acuerdos y procuradores

    ”’ </summary>

    ”’ <remarks></remarks>

    <Serializable()> _

    Partial Public Class ENAcuerdoprocurador

    Public Sub New()

    MyBase.New()

    End Sub

    Private m_Pk As Nullable(Of Integer)

    Private m_Fkacuerdo As Nullable(Of Integer)

    Private m_Fkprocurador As Nullable(Of Integer)

    ”’ <summary>

    ”’ Identificador único del acuerdo-procurador.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Pk() As Nullable(Of Integer)

    Get

    Return m_Pk

    End Get

    Set(ByVal value As Nullable(Of Integer))

    m_Pk = value

    End Set

    End Property

    ”’ <summary>

    ”’ Identificador del acuerdo.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Fkacuerdo() As Nullable(Of Integer)

    Get

    Return m_Fkacuerdo

    End Get

    Set(ByVal value As Nullable(Of Integer))

    m_Fkacuerdo = value

    End Set

    End Property

    ”’ <summary>

    ”’ Identificador del procurador.

    ”’ </summary>

    ”’ <value></value>

    ”’ <returns></returns>

    ”’ <remarks></remarks>

    Public Property Fkprocurador() As Nullable(Of Integer)

    Get

    Return m_Fkprocurador

    End Get

    Set(ByVal value As Nullable(Of Integer))

    m_Fkprocurador = value

    End Set

    End Property

    End Class

    End Namespace

    Ahora vamos a ver como enlazar las dos entidades en una línea…

    Supongamos que queremos recuperar los acuerdos de los procuradores que cuya fecha de finalización no ha llegado o es hoy.

    Dim listaAcuerdosVigentesFuturos = _

    (From acuerdo As EntidadesNegocio.Administracion.ENAcuerdo In colAcuerdos.ToList _

    Join ap As EntidadesNegocio.Administracion.ENAcuerdoprocurador In colAP.ToList _

    On acuerdo.Pk Equals ap.Fkacuerdo  Where acuerdo.Fechafin >= Now _

    Select acuerdo)

    From: Definimos la entidad origen (.ToList)

    Join: definimos la entidad con la que comparar (.ToList)

    On: Como en SQL definimos cuál es la relación entre las entidades.

    Where: Definimos la condición de filtrado.

    Select: Definimos el dato a recuperar, hemos puesto acuerdo, pero podríamos haber puesto ap

    o acuerdo.fechainicio, acuerdo.fechafin, ap.fkprocurador.

    Espero que con este ejemplo pueda recordar como se usa LINQ en el futuro y os sirva a vosotros…

    Sean felices desarrollando.

    Procedimiento almacenado

    27 Sep

    Como comenté, cambio de registro y dedico este blog a publicar artículos relacionados con mi trabajo, el desarrollo de aplicaciones web. Aclarar, que aunque intento que sirvan a aquellos desarrolladores sin amplios conocimientos, en este caso sobre procedimientos almacenados, lo publico como “copia de seguridad” de mis notas.

    A la faena…

    Voy a intentar mostraros como desarrollar un procedimiento almacenado, mostrando una serie de ejemplos y recordando algunas estructuras que se deberían conocer. La finalidad, que podaís crear vuestros procedimientos almacenados o resolver alguna duda que tengáis.

    Durante la creación de los procedimientos declararemos parametros, cursores, variables y nombres de procedimientos, que si no es obligarorio, si deberían seguir una serie de reglas para los Identificadores de Base de Datos.

    1.-Definición del procedimiento:

    CREATE PROCEDURE [dbo].[pa_Rellena_Tabla]

    “CREATE PROCEDURE”: Literal que indica que vamos a crear el procedimiento y por tanto es obligatorio.

    [esquema]: El nombre del esquema al que pertenece el procedimiento. Los procedimientos se enlazan a un esquema. Si no se especifica el nombre del esquema cuando se crea el procedimiento, se asigna automáticamente el esquema predeterminado del usuario que crea este procedimiento.

    [nombre_procedimiento]: Evite el uso del prefijo sp_ cuando asigne nombre a los procedimientos. SQL Server usa este prefijo para designar los procedimientos del sistema. Si usa el prefijo, puede provocar la ruptura del código de la aplicación si existe un procedimiento del sistema con el mismo nombre. El nombre del procedimiento no puede superar los 128 caracteres.

    [esquema].[nombre de procedimiento]:[miEsquema].[pa_miProceso]

    CREATE PROCEDURE [miEsquema].[pa_miProceso]

    Ya está creado el procedimiento almacenado.

    Ahora intentemos acercarnos a la realidad, creando unos procedimiento más reales.

     i.      Definición de procedimiento que nos devuelva un reslultado:

    CREATE PROCEDURE [miEsquema].[ pa_miProceso] @RespuestaEjecucion int output

    ii.      Definición de procedimiento que devuelva un resultado y reciba un parametro de entrada:

    CREATE PROCEDURE [miEsquema].[pa_miProceso] @RespuestaEjecucion int output, @Primer_Parametro as varchar(9)

    Si quieres que @Primer_Parametro sea opcional, has de asignarle un valor por defecto:

    CREATE PROCEDURE [dbo].[sp_miProceso] @RespuestaEjecucion int output, @Primer_Parametro as varchar(9)=’valor1’

    Si quieres que @Primer_parametro sea de tipo int, @Primer_Parametro int

    2.-Definición de variables y cursores

    declare @VarTexto nvarchar(max)

    declare @VarInt int

    declare @VarCursor as cursor

    3.-Asignar valores

    Asigna valor de texto:  set @VarTexto = ‘texto a incluir’

    Concatena valor a una variable: @VarTexto = @VarTexto + ‘ texto a concatenar’

    Asigna valor de numérico: set @VarInt = 1

    Asigna valor de una consulta sql, el campo ha de ser del mismo tipo que la variable: select @VarInt = id_campo from [tabla] where id_campo2 is null

    Asigna valor de una consulta set @VarCursor = cursor for select valor from tabla where condición

    4.-Ejemplo uso de un cursor

    Declaración de variables

    declare @MiCursor as cursor

    declare @ID_uno int

    declare @ID_dos int

    Asigna valores

    set @ID_dos = @Parametro_de_Entrada_Procedimiento_almacenado

    El valor del cursor son los datos obtenidos de una consulta.

    set @MiCursor = cursor for select campo1 from [esquema].[tabla] where id_tabla = @ID_dos

    Abre el cursor para poder usarlo

    open @MiCursor

    Asigna los valores del primer registro a nuestra variable

    fetch next from @MiCursor into @ID_uno

    Si la consulta seleccionase campo1,campo2 se asignarían así a sus variables.

    fetch next from @MiCursor into @VarCampo1, @VarCampo2

    Mientras el estado sea 0 indica que no ha llegado a EOF

    WHILE @@fetch_status = 0

    BEGIN

         Proceso a ejecutar con cada registro encontrado.

         Una vez terminado el proceso, asigna a la variable el valor del siguiente registro.    

          FETCH next FROM @MiCursor INTO @ID_uno

    END

    Importante, si no vas a trabajar más con el cursor lo cierras y destruyes para liberar la memoria.

    close @MiCursor

    deallocate @MiCursor

    5.-Ejecuciones dentro de un procedimiento almacenado.

    Dentro de un procedimiento almacenado normal, no de ejemplos del tipo Hola Mundo, se puede dar la necesidad de tener que trabajar con variables, que ya hemos visto, con vectores, que también o la necesidad de evaluar una condición o ejecutar un procedimiento almacenado.

    i. Ejecutar procedimientos almacenados

    Empezaremos por lo más sencillo, invocar un procedimiento almacenado dentro de otro procedimiento.

    Si no tiene parámetros: execute [nombre_procedimiento]

    Si tiene parámetros: execute [nombre_procedimiento] @ Parametro1, @Parametro2

    Esto se usa mucho, por ejemplo cuando queremos ejecutar una sentencia sql utilizamos este procedimiento almacenado del sistema, con el prefijo sp_ que no debemos usar:

    exec sp_executesql @sql

    En la variable @sql estaría la operación CRUD a realizar.

    Otro procedimiento almacenado del sistema es OBJECT_ID, que como su nombre indica devuelve el id de un objeto  ser tablas, así lo usaríamos:

    SET @object_id = OBJECT_ID(N'[nombre_esquema].[nombre_tabla]’);

    Si @object_id fuese 0 nos indicaría que no lo ha encontrado.

     En la misma línea está DB_ID, en este caso devuelve el id de la base de datos:

     SET @db_id = DB_ID(N’nombre_base_de_datos’);

    Si @db_id fuese 0 nos indicaría que no lo ha encontrado.

    ii.      Evaluar condiciones

    Recordando la estructura “IF”

    IF condición

    BEGIN

         Sentencias en caso afirmativo.

    END

    Recordando la estructura “IF, ELSE”

    IF condición

    BEGIN

         Sentencias en caso afirmativo.

    END

    ELSE

    BEGIN

    Sentencia en caso negativo.

    END

    Recordando la estructura “IF anidado”

    IF condición

    BEGIN

    Sentencias en caso afirmativo.

    END

    ELSE IF Condición_Else_if

    BEGIN

    Sentencias en caso afirmativo.

    END

    ELSE

    BEGIN

    Sentencias en caso negativo.

    END

    Ejemplo de uso IF

    Probemos evaluar la respuesta de una consulta sql.

    IF (select count(*) from [tabla] where id_campo = @ID_uno and campo2 = @ID_dos) = 0

    BEGIN

    Sentencias en caso de que no se encuentre ninguno.

    END

    ELSE

    BEGIN

         Sentencias en caso de que encuentre alguno.

    END

    iii.      Búcle WHILE

    Recordando la estructura del “While”

    WHILE condición

    BEGIN

    Proceso a ejecutar mientras se cumpla la condición.

    IMPORTANTE: Una vez terminado el proceso, hay que reasignar el valor siguiente a la condición para evitar el “bucle infinito”.

    Incremento de la variable a evaluar.

    END

    Ejemplo de uso del “while”;

    Lo vamos a realizar con un cursor, que viene siendo lo más lógico.

    Antes de evaluar la condición hay que asigar el primer valor.

    fetch next from @MiCursor into @ID_uno 

    Mientras el estado del cursor sea 0 no habremos llegado a EOF

    WHILE @@fetch_status = 0

    BEGIN    

    Proceso a ejecutar con cada registro encontrado.

             Terminado el proceso, asigna a la variable el valor del siguiente registro.

    FETCH next FROM @MiCursor INTO @ID_uno

    END

    Creación de un proceso almacenado.

    Vamos a crear un procedimiento que verifique que hay un usuario en la base de datos.

    USE [mi_base_de_datos]

    GO

    SET ANSI_NULLS ON

     GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE PROCEDURE [mi_esquema].[nombre_procedimiento] @Nombre char(8), @Existe int output

    AS 

    BEGIN

    SET NOCOUNT ON; 

    IF ( select count(id_usuarioFROM usiario where nombre_usuario = @Nombre = 0

    BEGIN

    @Existe = 0

    END

    ELSE

    BEGIN

    @Existe = 1

    END

    return @Existe

    END

    Hasta aquí, el primer paso para realizar un procedimiento almacenado, espero os sea útil…

     

    2013 Año de la serpiente.

    27 Mar

    El pasado 10 de Febrero, entramos en el año de la serpiente. Los años de la Serpiente suelen ser años terribles, dramáticos y desestabilizadores, en los que se puede cambiar el curso de la historia…

    Grandes acontecimientos mundiales sucedieron en años anteriores: La Revolución Rusa, la caída del Muro de Berlín, el final de la Guerra Fría, el ataque a las Torres Gemelas y al Pentágono, insurrecciones, revueltas, escándalos… que traen graves consecuencias y pueden desestabilizar un país, una región o una casa.

     

    foto: conesenciademujer.com

    foto: conesenciademujer.com

    Sumo un acontecimiento, que no sé si llegará a desestabilizar un país y que conste que no lo hago con esta intención, después de casi un año con este blog que he orientado al desarrollo de la persona y la empresa en esta nueva era de las comunicaciones que estamos viviendo, he decidido “organizarme” y dar otro aire a este blog, más orientado a mí trayectoria profesional actual.

    En la actualidad soy desarrollador .Net contra bases de datos SQL, así que utilizaré este blog para ir dejando códigos de desarrollos que me hayan costado más o menos realizar y que quizá puedan arrojar algo de luz a los siguientes desarrolladores llegados hasta aquí vía google o reblog.

    Para los que ya me conocéis por mi intención de mejorar el #TratoHumano en las empresas, indicaros que seguiré publicando en la medida de lo posible, siempre menos de lo que quisiese, en Works & Dreams, dónde ya he migrado algunos de los artículos que publiqué aquí.

    Bienvenidos y hasta pronto.

    La que has liado

    Fotografiar con palabras, nuestro momento, nuestra época. Del 1.1 al 2.0

    TERZERO

    Pio Baroja

    El árbol inútil

    Blog de cuentos, libros y mala poesía

    Lo que de verdad importa

    somos dueños de nuestro destino, inventores de nuestro futuro y nuestra felicidad...

    Frikstation

    Pasión por el mundo de la televisión, el cine, los videojuegos y su merchandising.

    A %d blogueros les gusta esto: