post icon

Como programar en n-Capas con C# (Parte 5)

Con ésta entrega cumpliremos con la capa de Presentación, utilizaremos todo lo que hemos visto hasta ahora aplicados a una interfaz de usuario, y como lo prometí, lo veremos implementado en winForm como en webForm.

El primer ejemplo será Desktop, crearemos un formulario con una apariencia semejante al que ven en la imagen.

frmCliente

Evidentemente, un sistema real no lo harán así, el botón conectar emula el comportamiento de una pantalla de login, el boton crear mandará a la BBDD los datos de la caja, Listar rellenará la grilla y Buscar By Id se encargará de devolvernos un registro a partir de lo que carguemos en la caja de Id. Otra implementación interesante sería agregarle un identity a la tabla cliente, pero para el ejemplo ya servirá esto. Para esto crearemos 2 proyectos más dentro de nuestra solución, uno será una aplicación Windows Form con Visual C#, y la otra un sitio Web.

El código que pondremos en el botón conectar es como sigue,  recuerden que es conveniente armarlo dinamicamente con una pantalla de login especialmente el usuario y el pass. Con esto logramos armar toda la capa de Acceso a Datos, no se mantiene conectada la aplicación, sino solo sus valores de conexión en memoria.

1
2
3
4
5
6
7
8
9
try
{
	Conexion.IniciarSesion("127.0.0.1", "Queryable", "sa", "123");
	MessageBox.Show(String.Format("{0}", "Se conecto exitosamente"));
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
}

Para crear un nuevo cliente instanciamos un objeto cliente del tipo Cliente, le seteamos sus atributos, a partir de los valores de la caja de texto, e invocamos el método crear enviandole el nuevo objeto cliente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var cliente = new Cliente();
try
{
	cliente.IdCliente = Convert.ToInt16(txtIdCliente.Text);
	cliente.Descripcion = txtDescripcionCliente.Text;
	cliente.Sigla = txtSiglaCliente.Text;
 
	cliente.Crear(cliente);
	MessageBox.Show(String.Format("{0}", "Se creo exitosamente"));
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
}

Luego de esto escribimos el código de listado de todos los clientes, y lo cargamos en la grilla. Se dan cuenta que necesitamos muy pocas lineas de código en la capa de Presentación, y que no tiene una dependencia de la BBDD?. Si se dan cuenta, cuando vamos a devolver muchos registros no podemos utilizar un montón de instancias de Cliente, sino simplemente devolvemos un DataTable, DataSet o DataReader.

1
2
3
4
5
6
7
8
9
var cliente = new Cliente();
try
{
	grilla.DataSource = cliente.Listar();
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
}

Finalmente el código de búsqueda quedaría algo asi. Cómo sabemos que si buscamos por la PK, siempre nos devolverá un sólo registro, lo podemos crear como un objeto Cliente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var cliente = new Cliente();
try
{
	cliente = cliente.Listar(Convert.ToInt16(txtIdCliente.Text));
 
	if (cliente != null)
	{
		txtDescripcionCliente.Text = cliente.Descripcion;
		txtSiglaCliente.Text = cliente.Sigla;
	}
	else
	{ MessageBox.Show(String.Format("{0}", "No existia el cliente buscado")); }
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
}

El código completo quedaría así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using System;
using System.Windows.Forms;
using AccesoDatos;
using AccesoDatos.Orm;
 
namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void btnConectar_Click(object sender, EventArgs e)
        {
            try
            {
                Conexion.IniciarSesion("127.0.0.1", "Queryable", "sa", "***");
                MessageBox.Show(String.Format("{0}", "Se conecto exitosamente"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void btnListar_Click(object sender, EventArgs e)
        {
            var cliente = new Cliente();
            try
            {
                grilla.DataSource = cliente.Listar();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void btnCrear_Click(object sender, EventArgs e)
        {
            var cliente = new Cliente();
            try
            {
                cliente.IdCliente = Convert.ToInt16(txtIdCliente.Text);
                cliente.Descripcion = txtDescripcionCliente.Text;
                cliente.Sigla = txtSiglaCliente.Text;
 
                cliente.Crear(cliente);
                MessageBox.Show(String.Format("{0}", "Se creo exitosamente"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void btnBuscarById_Click(object sender, EventArgs e)
        {
            var cliente = new Cliente();
            try
            {
                cliente = cliente.Listar(Convert.ToInt16(txtIdCliente.Text));
 
                if (cliente != null)
                {
                    txtDescripcionCliente.Text = cliente.Descripcion;
                    txtSiglaCliente.Text = cliente.Sigla;
                }
                else
                { MessageBox.Show(String.Format("{0}", "No existia el cliente buscado")); }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

Con respecto a la parte web, tendremos 2 partes, el código ASP.net, y el c#, veamoslo, se los dejo completamente de una:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Cliente.aspx.cs" Inherits="Cliente" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="frmCliente" runat="server">
    <div>
 
        <asp:Label ID="Id" runat="server" Text="Id:  "></asp:Label>
        <asp:TextBox ID="txtIdCliente" runat="server"></asp:TextBox>
        <br />
        <asp:Label ID="Label1" runat="server" Text="Descripcion:  "></asp:Label>
        <asp:TextBox ID="txtDescripcionCliente" runat="server"></asp:TextBox>
        <asp:TextBox ID="txtuser" runat="server">sa</asp:TextBox>
        <br />
        <asp:Label ID="Label2" runat="server" Text="Siglas:  "></asp:Label>
        <asp:TextBox ID="txtSiglasCliente" runat="server"></asp:TextBox>
        <br />
        <hr style="margin-top: 0px; margin-bottom: 0px" />
        <asp:GridView ID="grilla" runat="server" CellPadding="4" ForeColor="#333333" 
            GridLines="None">
            <AlternatingRowStyle BackColor="White" />
            <EditRowStyle BackColor="#2461BF" />
            <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
            <RowStyle BackColor="#EFF3FB" />
            <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
            <SortedAscendingCellStyle BackColor="#F5F7FB" />
            <SortedAscendingHeaderStyle BackColor="#6D95E1" />
            <SortedDescendingCellStyle BackColor="#E9EBEF" />
            <SortedDescendingHeaderStyle BackColor="#4870BE" />
        </asp:GridView>
        <asp:Label ID="Label3" runat="server" Text="Estado:"></asp:Label>
        <asp:Label ID="lblEstado" runat="server"></asp:Label>
        <br />
        <asp:Button ID="btnConectar" runat="server" Text="Conectar" 
            onclick="btnConectar_Click" />
        <asp:Button ID="btnCrear" runat="server" onclick="btnCrear_Click" 
            Text="Crear" />
        <asp:Button ID="btnListar" runat="server" onclick="btnListar_Click" 
            Text="Listar" />
        <asp:Button ID="btnListarById" runat="server" onclick="btnListarById_Click" 
            Text="Listar By Id" />
        <br />
 
    </div>
    </form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
 
// using AccesoDatos;
 
public partial class Cliente : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
    protected void btnConectar_Click(object sender, EventArgs e)
    {
        try
        {
            lblEstado.Text = "";
            AccesoDatos.Conexion.IniciarSesion("127.0.0.1", "Queryable", "sa", "***");
            lblEstado.Text = String.Format("{0}", "Se conecto exitosamente");
        }
        catch (Exception ex)
        {
            lblEstado.Text = String.Format(ex.Message);
        }
    }
    protected void btnListar_Click(object sender, EventArgs e)
    {
        var cliente = new AccesoDatos.Orm.Cliente();
        try
        {
            grilla.DataSource = cliente.Listar();
            grilla.DataBind();
            lblEstado.Text = String.Format("{0}", "Se listo exitosamentë");
        }
        catch (Exception ex)
        {
            lblEstado.Text = ex.Message;
        }
    }
    protected void btnCrear_Click(object sender, EventArgs e)
    {
        var cliente = new AccesoDatos.Orm.Cliente();
        try
        {
            cliente.IdCliente = Convert.ToInt16(txtIdCliente.Text);
            cliente.Descripcion = txtDescripcionCliente.Text;
            cliente.Sigla = txtSiglasCliente.Text;
 
            cliente.Crear(cliente);
            lblEstado.Text = String.Format("{0}", "Se creo exitosamente");
        }
        catch (Exception ex)
        {
            lblEstado.Text = ex.Message;
        }
    }
    protected void btnListarById_Click(object sender, EventArgs e)
    {
        var cliente = new AccesoDatos.Orm.Cliente();
        try
        {
            cliente = cliente.Listar(Convert.ToInt16(txtIdCliente.Text));
 
            if (cliente != null)
            {
                txtDescripcionCliente.Text = cliente.Descripcion;
                txtSiglasCliente.Text = cliente.Sigla;
            }
            else
            { lblEstado.Text = String.Format("{0}", "No existia el cliente buscado"); }
        }
        catch (Exception ex)
        {
            lblEstado.Text = ex.Message;
        }
    }
}

Si pueden agregar/aportar mejoras y funcionalidad a estas clases, serán bienvenidas :) de hecho éste código lo creo un MVP de Microsoft y yo le agregue algunas funcionalidades..
Parte 1 | Parte 2 | Parte 3 | Parte 4
Edit [2010/08/05]:

A pedido de JR, les subo un ejemplo práctico de las 3 capas con Firebird como Base de Datos, C# el lenguaje. Ya están incluidas dentro del proyecto el Data Provider y la BD de ejemplo. El password del fichero es www.devtroce.com, que lo disfruten!

Descargar Ejemplo!

82 Comentarios

Deja tu Comentario
  1. marcelom ARGENTINA Internet Explorer Windows
    14 diciembre 2010 at 14:36 #

    Hola GeekZero. Antes que nada muchas gracias por este excelente post. Quería hacerte una pregunta. En la parte 1 del post dices que el código puede utilizarse desde VS2005 con el framework 2.0 en adelante, sin embargo yo bajé código ejemplo para Firebird y en alguno de los .cs aparece un using Linq. ¿El código de ese ejemplo puedo utilizarlo en VS2005 o no ? entiendo que LINQ es de VS2008 en adelante.
    Gracias nuevamente. Marcelo

    • GeekZero PARAGUAY Mozilla Firefox Windows
      14 diciembre 2010 at 15:03 #

      Hola Marcelo, pasa que el ejemplo con firebird lo agregue recientemente a pedido de uno de los lectores y ya no cuide ese detalle, pero el codigo que ves en la pagina esta basado en el 2.0, si se me escapo en algún lugar simplemente sacalo del using ya que no utilizo en las capas ninguna de las caracteristicas Linq

      • marcelom ARGENTINA Internet Explorer Windows
        14 diciembre 2010 at 15:09 #

        Gracias por tu pronta respuesta. Voy a probar sin el using y cualquier cosa te aviso. Saludos.

        • marcelom ARGENTINA Internet Explorer Windows
          18 diciembre 2010 at 22:15 #

          Geekzero, en GDatos dice
          // asignar el string sql al command
          var com = Comando(procedimientoAlmacenado);

          La keyword VAR ¿no es de C# 3.0 ? no me compila en vs2005.
          Gracias, Marcelo.

        • GeekZero PARAGUAY Google Chrome Windows
          19 diciembre 2010 at 04:12 #

          Asi mismo es de c# 3.0, originalmente cuando lo que subi estuvo para la version 2, pero tuvimos unos problemas con la db de wordpress y se perdieron algunos datos y tuve que reconstruir con lo que tenia, este tema lo hice casi completo de nuevo y como lo habia actualizado ya para mi vs 2008 quedaron algunos problemas como este, me es dificil hacerme de tiempo para reponer todo como estaba antes, pero prometo que cuando pueda lo iré haciendo..

  2. Jose E. MEXICO Mozilla Firefox Windows
    14 diciembre 2010 at 12:33 #

    Saludos, gracias por poner este ejemplo en la web. Mi pregunta es que porque solo puedo iniciar sesión si tengo al usuario sa con un password. He intentado iniciar sesión con un usurio que yo creo en sql server y no funciona, me marca: “Error de inicio en el usuario sa”. ¿Saben a que se debe?

    Pongo el código tal cual y no sirve, mi usuario tiene todos los permisos, etc.
    Conexion.IniciarSesion(“127.0.0.1″, “MyBD”, “myusuario”, “mypass”);

    • GeekZero PARAGUAY Mozilla Firefox Windows
      14 diciembre 2010 at 15:06 #

      Y funciona tu login del sa desde el SSMS? puedes revisar en la clase SqlServer al momento de construir la cadena de conexion si todo esta bien..

      • Jose E. MEXICO Mozilla Firefox Windows
        14 diciembre 2010 at 15:38 #

        Gracias por tu respuesta, si serve en el Management Studio. Mira este es el codigo que tiene la clase SqlServer para crear la cadena:

        sCadena.Append(“data source=;”);
        sCadena.Append(“initial catalog=;”);
        sCadena.Append(“user id=;”);
        sCadena.Append(“password=;”);
        sCadena.Append(“persist security info=True;”);
        sCadena.Append(“user id=sa;packet size=4096″);
        sCadena.Replace(“”, Servidor);
        sCadena.Replace(“”, Base);
        sCadena.Replace(“”, Usuario);
        sCadena.Replace(“”, Password);

        no se si sea por esta linea:
        sCadena.Append(“user id=sa;packet size=4096″);

        ¿Tendrás idea?

      • Jose E. MEXICO Mozilla Firefox Windows
        14 diciembre 2010 at 15:39 #

        Gracias por tu respuesta, si serve en el Management Studio. Mira este es el codigo que tiene la clase SqlServer para crear la cadena:

        sCadena.Append(“data source=;”);
        sCadena.Append(“initial catalog=;”);
        sCadena.Append(“user id=;”);
        sCadena.Append(“password=;”);
        sCadena.Append(“persist security info=True;”);
        sCadena.Append(“user id=sa;packet size=4096″);
        sCadena.Replace(“”, Servidor);
        sCadena.Replace(“”, Base);
        sCadena.Replace(“”, Usuario);
        sCadena.Replace(“”, Password);

        no se si sea por esta linea:
        sCadena.Append(“user id=sa;packet size=4096″);

        ¿Tendrás idea?

        • GeekZero PARAGUAY Mozilla Firefox Windows
          14 diciembre 2010 at 15:51 #

          El problema es como armas la cadena de conexion, el metodo replace no esta bien utilizado. Fijate como esta en el original y como se utiliza el StringBuilder. Con eso ya solucionarias el problema

  3. Miguel MEXICO Mozilla Firefox Windows
    5 diciembre 2010 at 16:20 #

    La conexion se abre solo cuando ejecutas algun proceso de lectura o escritura, y se cierra cuando finaliza.. no hace falta que escribas en capa alta eso..

    Saludos mencionaste esto hace algunos post pero ya analize el código y no veo en ninguna parte que abra la conexión antes de ejecutar/leer algo y al terminar la cierre.

    Por ejemplo aqui:
    // Ejecuta un query sql.
    public int EjecutarSql(string comandoSql)
    { return ComandoSql(comandoSql).ExecuteNonQuery(); }

    Esque he tenido problemas con mis proyectos anteriores que se conectaban remotamente y no cerraba la conexion al ejecutar comandos. Espero con este gran ejemplo que publicas ya no tenga este tipo de problemas.

  4. sussy MEXICO Internet Explorer Windows
    27 noviembre 2010 at 01:25 #

    Hola, me sirvió mucho este ejemplo y lo utilizé para un proyecto escolar. Pero, me gustaria me pudieran ayudar.

    Desde este boton “Guardar” hago lo siguiente cada que se guarda un registro…..
    private void btnAgregar_Click(object sender, EventArgs e)
    {//Agrega un producto al detalle del pedido
    int canti = Convert.ToInt32(txtCantidad.Text);
    idproducto = gridProductos.CurrentRow.Cells[0].Value.ToString();
    producto = gridProductos.CurrentRow.Cells[1].Value.ToString();
    tamaño = gridProductos.CurrentRow.Cells[2].Value.ToString();
    precio = gridProductos.CurrentRow.Cells[3].Value.ToString();
    descripcion = gridProductos.CurrentRow.Cells[5].Value.ToString();
    //Se llama al metodo AgregarProducto enviandole el producto a guardar
    idOrdenPedido = AgregarProducto(idproducto, producto, tamaño, precio, descripcion, canti);}

    Tengo este método para insertar un registro ……

    public int AgregarProducto(string idproducto, string producto, string tamaño, string precio, string descripcion, int cantidad)
    {

    var pedido = new Pedidos();
    pedido.IdProd = Convert.ToInt32(idproducto);
    pedido.nomProducto = producto;
    pedido.tamano = tamaño;
    pedido.precioProducto = Convert.ToDecimal(precio);
    pedido.descripcion = descripcion;
    pedido.cantidad = cantidad;
    pedido.subtotal = Convert.ToDecimal(pedido.cantidad * pedido.precioProducto);

    // Envia los datos al metodo Insertar Productos y regresa el id de OrdenPedido
    return Convert.ToInt32(pedido.insertarProdSelec(pedido));

    }

    y le envia los parametros a este otro metodo que ejecuta el procedimiento almacenado……

    public int insertarProdSelec(Pedidos pedido)
    {
    int idObtenido = Convert.ToInt32(Conexion.GDatos.Ejecutar(“paOrdenPedido_Agregar”,
    pedido.IdProd,
    pedido.nomProducto,
    pedido.tamano,
    pedido.precioProducto,
    pedido.descripcion,
    pedido.cantidad,
    pedido.subtotal, 7),);

    return idObtenido;

    }

    Este es mi procedimiento almacenado

    ALTER PROCEDURE paOrdenPedido_Agregar
    @idOrdenPedido int OUTPUT,
    @IdProd int,
    @nomProducto nvarchar(50),
    @tamano nvarchar(50),
    @precioProducto decimal (18,0),
    @descripcion nvarchar(100),
    @cantidad int,
    @subtotal decimal (18,0)

    AS

    INSERT INTO tbDetallePedido
    (idProducto, nomProducto, tamano, precioProducto,
    descripcion, cantidad, subtotal)

    values (
    @IdProd, @nomProducto, @tamano, @precioProducto,
    @descripcion,@cantidad, @subtotal);

    SELECT @idOrdenPedido = SCOPE_IDENTITY()
    RETURN

    NOSE QUE ESTOY HACIENDO MAL NO ME DEVUELVE NADA

    O debo usar el

    public object TraerValorOutput(string procedimientoAlmacenado)
    {
    var com = Comando(procedimientoAlmacenado);
    com.ExecuteNonQuery();
    Object resp = null;

    // recorrer los parametros del SP
    foreach (IDbDataParameter par in com.Parameters)
    // si tiene parametros de tipo IO/Output retornar ese valor
    if (par.Direction == ParameterDirection.InputOutput || par.Direction == ParameterDirection.Output)
    resp = par.Value;
    return resp;
    }

    • GeekZero PARAGUAY Google Chrome Windows
      27 noviembre 2010 at 02:45 #

      Hola Sussy, puede ser variante aun la respuesta, pero estimo que una posibilidad de error se da con tu llamada al SCOPE_IDENTITY, prueba con @@Identity y luego cuentame que tal te fue..

      1
      
      SELECT @idOrdenPedido = @@Identity();
      • sussy MEXICO Internet Explorer Windows
        27 noviembre 2010 at 12:10 #

        como puedo enviar la variable @idOrdenPedido dede c# esa parte no me queda muy clara, y como se envia. Bueno de acuerdo a esta metodologia ya que encontre un ejemplo asi:using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
        {
        conn.Open();

        SqlCommand command = new SqlCommand(“sp_ContactoInsert”, conn);
        command.CommandType = CommandType.StoredProcedure;

        SqlParameter paramId = new SqlParameter(“Id”, SqlDbType.Int);
        paramId.Direction = ParameterDirection.Output;
        command.Parameters.Add(paramId);

        command.Parameters.AddWithValue(“Nombre”, nombre);
        command.Parameters.AddWithValue(“Direccion”, direccion);
        command.Parameters.AddWithValue(“FechaNacimiento”, fechaNacimiento);

        int rowsAffected = command.ExecuteNonQuery();

        if (rowsAffected > 0)
        {
        return Convert.ToInt32(command.Parameters["Id"].Value);
        }
        else
        return -1;

        }

        y con este procedimiento almacenadoALTER PROCEDURE dbo.sp_ContactoInsert

        @Id int OUTPUT,
        @Nombre varchar(50),
        @Direccion varchar(50),
        @FechaNacimiento DateTime

        AS
        INSERT INTO Contactos
        (NombreCompleto
        ,Direccion
        ,FechaNacimiento)
        VALUES (@Nombre,
        @Direccion,
        @FechaNacimiento);

        SELECT @Id = SCOPE_IDENTITY()

        RETURN

        y funciona bien, pero claro que tiene todo el codigo en la forma, como se puede implementar un ejemplo parecido a este pero aplicado a esta metodologia.

        que devuelva el id identitity.

        Bueno muchas gracias!!!

    • GeekZero PARAGUAY Google Chrome Windows
      27 noviembre 2010 at 12:14 #

      Ya creo comprender tu pregunta, le he respondido lo mismo a racman. Debes utilizar el metodo TraerValorEscalar, este es el ejemplo que le di en su caso:

      1
      
      int salida = Convert.ToInt32(Conexion.GDatos.TraerValorEscalar("CalcTasa", "Entrada"));
  5. GeekZero PARAGUAY Google Chrome Windows
    25 noviembre 2010 at 06:38 #

    Hola Jorge, definitivamente debes agregar una referencia, das clic derecho sobre tu proyecto forms, agregar referencia, en la pestaña proyectos, elijes la bibioteca de clases y generas de nuevo la solucion..

  6. Jorge MEXICO Mozilla Firefox Windows
    25 noviembre 2010 at 01:34 #

    Disculpa tengo ambos proyectos (windows forms) y libreria de clases dentro de la misma solución. Pero cuando en un form pongo:

    using AccesoDatos;
    using AccesoDatos.Orm;

    No me los admite, ¿es necesario agregar la referencia o cual es motivo?

  7. GeekZero PARAGUAY Google Chrome Windows
    19 noviembre 2010 at 12:59 #

    Una sola vez, hasta cerrar la aplicación. Cada vez que ejecutas algo se conecta y se desconecta al terminar, pero no lo controlas en alto nivel. El login inicial solamente sirve para cargar los valores de conexion que se usaran durante este abierto tu app..

    • MIGUEL MEXICO Mozilla Firefox Windows
      23 noviembre 2010 at 10:57 #

      ¿En que evento de mi aplicacion debo cerrar la conexión con la base de datos?

      ¿Que pasa si se apaga el equipo o se cierra la aplicacion por algun fallo, se mantendría una conexión activa?

      Disculpa tantas preguntas pero es algo que me he preguntado durante mucho tiempo y no he encontrado nada, pero al parecer tu tienes la respuesta =)

      • GeekZero PARAGUAY Google Chrome Windows
        23 noviembre 2010 at 20:31 #

        La conexion se abre solo cuando ejecutas algun proceso de lectura o escritura, y se cierra cuando finaliza.. no hace falta que escribas en capa alta eso..

  8. Miguel MEXICO Mozilla Firefox Windows
    19 noviembre 2010 at 00:27 #

    En mi login solo realizo el
    Conexion.IniciarSesion(“127.0.0.1″, “Queryable”, “sa”, “***”);

    ¿Y en todas mi clases y formas ya no tengo que volver a Iniciar Sersion?

    ¿debo conectarme antes de ejecutar un comando y desconectarme cuando se ejecute? ¿O no es necesario?

    Gracias. Excelente aporte.

  9. cdlesca ARGENTINA Mozilla Firefox Windows
    8 noviembre 2010 at 09:11 #

    Nuevamente mil gracias por tu tiempo. He bajado el ejemplo y estoy tratando de hacerlo andar en un boton de un form, pero no logro pasar el resultado de lo que devuelve el metodo listar() a un datasource de una grilla, pero evidentemente es un problema mio.

    Mil gracias nuevamente.

  10. cdlesca ARGENTINA Mozilla Firefox Windows
    7 noviembre 2010 at 21:34 #

    Hola GeekZero.

    Otra vez miles de gracias por la respuesta.

    Utilizando tu ejemplo, he hecho esto, a ver si esta bien.
    He creado una clase que ha he llamado ColeccionClientes
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using AccesoDatos.Orm;

    namespace BibliotecaDeClases
    {
    public class ClaseColeccionClientes :List
    {

    }

    }
    He tenido que hacer el using de AccesoDatos.Orm ya que necesito la definicion de la clase Cliente que tu haz hecho.
    Y he hecho un mentodo en Cliente para llenar esta coleccion

    public BibliotecaDeClases.ClaseColeccionClientes LlenarColeccion()
    {
    var ListaClientes = new BibliotecaDeClases.ClaseColeccionClientes();
    DataSet prueba = new DataSet();
    prueba = Conexion.GDatos.TraerDataSet(“slcCliente”);
    // MessageBox.Show(prueba.TableName.ToString());

    foreach (DataRow row in prueba.Tables[prueba.Tables.Count - 1].Rows)
    {
    Cliente uncliente = new Cliente();
    uncliente.IdCliente = Convert.ToInt16(row["idCliente"].ToString());
    uncliente.Descripcion = row["DescripcionCliente"].ToString();
    uncliente.Sigla = row["Siglas"].ToString();
    ListaClientes.Add(uncliente);
    }
    return ListaClientes;
    }

    Le he agregado un boton a la aplicacion y he puesto este codigo
    Cliente uncliente = new Cliente();
    grilla.DataSource = uncliente.LlenarColeccion();

    donde desde luego veo lo mismo que tu pones en el boton LISTAR, pero de esta manera obtengo los datos yo y los puedo manejar, con un datatable que es lo que devuelve Cliente.Listar() no se como recorrerlos y obtenerlos a los datos.

    Nuevamente muchisimas gracias por tu tiempo y tu respuesta. Sos realmente muy amable.

    • GeekZero PARAGUAY Google Chrome Windows
      7 noviembre 2010 at 22:03 #

      Fijate en esto, te pondré un ejemplo simple sin conexion a BD, lo que intentaré es ilustrarte el uso del retorno de un listado de un tipo de clase. No debes crear ninguna clase extra para ello, simplemente el tu clase base tendrá un método que retornará un listado de su mismo tipo, y luego será consumido en algun lugar.
      En este ejemplo veras una clase persona con 3 atributos, los cuales cargaré por código manualmente (y tu lo harás a partir de algun DataTable) luego retornare un listado de personas y en el metodo recorrer listado invocaré al método que retorna la lista, lo recorreré y se imprimirá en la consola del VS.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      
       
      using System.Collections.Generic;
       
      namespace WindowsFormsApplication2
      {
      class Personas
      {
          private int Id { set; get; }
          private string Nombres  { set; get; }
          private string Documento { set; get; }
       
          public List<Personas> Listar()
          {
              var persona1 = new Personas {Id = 1, Nombres = "Julian Mereles", Documento = "434"};
              var persona2 = new Personas { Id = 2, Nombres = "Mirella Gutierrez", Documento = "657" };
              var persona3 = new Personas { Id = 3, Nombres = "Patricia Gomez", Documento = "435" };
       
              var personas = new List<Personas>();
              personas.Add(persona1);
              personas.Add(persona2);
              personas.Add(persona3);
              return personas;
          }
       
          public void RecorrerListado()
          {
              var personas = Listar();
              foreach (var persona in personas)
              {
                  System.Console.WriteLine(string.Format("Usuario id: {0} con nombre: {1} y documento: {2}.", persona.Id, persona.Nombres, persona.Documento));
              }
          }
      }
      }
  11. cdlesca ARGENTINA Mozilla Firefox Windows
    7 noviembre 2010 at 16:30 #

    Hola. Ante todo mil gracias por este ejemplo que realmente sirve y mucho. En mi caso estoy empezando con C# y programacion en n capas, asi que estoy viene de maravillas. Pero como buen principiante, tengo una duda que estoy seguro que esta resuelta en el ejemplo y no la puedo ver.
    Hay muchisimos caso en una aplicacion sea o no en capas, donde vos tenes que llamar a un store procedure, y con los registros que te devuelve hacer algun tipo de operacion, recorrelos, etc.
    Dento de los metodos que vos tenes con cual puedo hacerlo, porque por ejemplo el traerdatatable me devuelve una tabla y tendria que recorrer fila por fila y columna por columna. Normalmente lo que hago es recorrer las filas y ya se como se llaman las columnas (campos de la tabla), ya se aca son objetos. Con un SqlDataReader podria hacerlo como te digo, pero no usaria todo el potencial de tu ejemplo.
    Espero se haya entendido.

    Aca te dejo el ejemplo que te comento, pero hecho no utilizando el potencial de tu codigo.
    public override ClaseLegajo ObtenerLegajo(int PNroLegajo)
    {
    SqlConnection C = this.ObtenerConexion();
    SqlDataReader DR = this.EjecutarQuery(“Select nro_legajo,nombre from per_legajo where nro_legajo=” + PNroLegajo, C);
    ClaseLegajo UnLegajo = null;
    if (DR.HasRows)
    {
    DR.Read();
    UnLegajo = new ClaseLegajo();
    UnLegajo.NroLegajo = Convert.ToInt32(DR["nro_legajo"]);
    UnLegajo.Nombre = DR["nombre"].ToString();
    UnLegajo.Agentes = ObtenerColeccionAgente(Convert.ToInt32(DR["nro_legajo"]));
    UnLegajo.Agentes.AsignarLegajo(UnLegajo);
    }
    DR.Close();
    C.Close();
    return UnLegajo;
    }

    De esta manera al menos a mi se me hace mas facil el acceso a los datos. Pero me gustaria utilizar tu codigo que es rapidisimo y efectivo.

    Desde ya mil gracias.

    • GeekZero PARAGUAY Google Chrome Windows
      7 noviembre 2010 at 20:34 #

      Hola Cdlesca, si he entendido bien quieres un metodo que devuelva un conjunto de objetos del tipo de tu clase creada, en este caso legajo. Para ello tienes varias posibilidades.

      • La primera es devolver un DataTable o DataSet ya que ambos son objetos genericos que no van ligados a un motor especifico de base de datos y podrás cambiarlo sin tener que modificar tu codigo de la app.
      • La segunda opción es trabajar con un DateReader, pero como objeto es dependiente del driver de un motor especifico puedes usar su objeto de Interfaz, el IDataReader.
      • Otra solución y posiblemente la más elegante es retornar un Array del tipo Legajos[], así vas cargando el mismo con los datos leídos desde un DataTable o IDataReader y luego desde la clase que lo incova lo vas recorriendo con un foreach

      Espero te sirva de ayuda ésto, si necesitas más ayuda hazmelo saber.

  12. sussy MEXICO Mozilla Firefox Windows
    5 noviembre 2010 at 18:48 #

    Error mi conexión a la base de datos

    Conexion.IniciarSesion(“SUSY-PC\\SQLEXPRESS”, “bdEjemploCapas”, “SUSY-PC\\SUSY”, ” “);

    me dice un error, esta por autentificación de windows y no tiene pass para entrar a la bd.

    En otros ejemplod me conecto de forma muy similar pero aqui no se proque no me deja

  13. racman COLOMBIA Internet Explorer Windows
    14 octubre 2010 at 17:53 #

    GeekZero, crees q seria bueno iniciar otro hilo, con las dudas del post… pues ya esta como largo…

    • GeekZero PARAGUAY Google Chrome Windows
      14 octubre 2010 at 20:31 #

      Para que sea mas legible podemos responder solo al primer nivel.. o puedes crear un hilo en el foro que tiene mucho mas espacio ya que aprovecha casi toda la resolución de la pantalla
      Si te devuelve cero deberías verificar tu SP, lo haz probado con los mismos datos desde tu SQL? o cambiado de valores a los parametros? si estás seguro que algo no funciona bien sube parte de tu proyecto en el foro para intentar replicar la falla.

  14. aacalvillo MEXICO Google Chrome Windows
    13 octubre 2010 at 20:47 #

    Hola que tal:

    Tengo el siguiente problema, ya tengo un procedimiento almacenado en el cual consultare un nombre de usuario y password filtrado por un numero de sucursal, como le hago para enviarle los parametros porque no me devuelve nada tu ejemplo, ni siquiera con un solo parametro.

    Ejem:

    grilla.DataSource = Usuario.Validar_Usuario(“aacalvillo”,12345,400);

    no devuelve nada.

    Saludos

    • GeekZero PARAGUAY Google Chrome Windows
      13 octubre 2010 at 21:07 #

      Hola aacalvillo, con los datos que me pasas no puedo saber que estas haciendo, asumo que Usuario es alguna clase y Validar_Usuario uno de sus metodos.
      Como no veo el código que hay dentro de tu método no puedo decirte que está mal. Sería bueno que te expliques un poco mejor, que querés cargar en la grilla o que valores esperas que retorne tu procedimiento.
      Como va a ser un poco largo los datos que necesitas pasarme, sería bueno que crees un hilo en el foro ya que hay más espacio para ello, con un tu código C# y T-SQL podría ayudarte con gusto..

      • aacalvillo MEXICO Google Chrome Windows
        13 octubre 2010 at 21:14 #

        Perdon por la falta de datos, efectivamente Usuario es una clase, solo le cambie de nombre a la que tienes de ejemplo llamaca clientes, todo es lo mismo solo que quiero mandarle un par de parametros pero estoy viendo que si devuelve el resultado, el problema es que se vuelve null el return una ves que la clase slcClientebyId lo retorna para llenar la grilla.

        que podre hacer??

        • GeekZero PARAGUAY Google Chrome Windows
          13 octubre 2010 at 21:33 #

          Y comprobaste desde tu SQL Management Studio ese SP te devuelve valores con los mismo parametros?

          1. La regla de negocio que deseas implementar no me cierra bien, cada vez que consultas algo en la capa de presentacion le enviarás el usuario y pass de conexion? o eso valores representan otra cosa?
          2. Que datos debes mostrar en la grilla?
        • aacalvillo MEXICO Google Chrome Windows
          13 octubre 2010 at 21:53 #

          Sera para validacion de usuarios del sistema, no a la bd, la consulta debe retornarme los datos del usuario y sera para validar si el password es correcto.

          Pero el error era mio no note que lo que me retornaba no era un datatable por eso no mostraba nada en la grilla.

          Saludos

  15. racman COLOMBIA Internet Explorer Windows
    11 octubre 2010 at 16:15 #

    necesito una ayuda…
    tengo un procedimiento q recibe dos parametros unos de entrada y otro de salida, como puedo hacer el llamado a este sp

    int salida;
    Conexion.GDatos.TraerDataSet(“CalcTasa”, ["Entrada", salida]);

    // proceso salida

    • GeekZero PARAGUAY Google Chrome Windows
      11 octubre 2010 at 22:26 #

      Hola Racman, si tienes un solo output con esto puedes capturarlo:

      1
      
      int salida = Convert.ToInt32(Conexion.GDatos.TraerValorEscalar("CalcTasa", "Entrada"));
      • racman COLOMBIA Internet Explorer Windows
        12 octubre 2010 at 10:52 #

        el codigo me marca error, me dice que falta un parametro…

        Procedure or function ‘CalcTasa’ expects parameter ‘@Salida’, which was not supplied

        desde SQL ejecuto asi el SP.

        DECLARE @Salida int
        EXECUTE [dbo].[CalcTasa] ‘Entrada’,@Salida OUTPUT
        select @Salida

        • GeekZero PARAGUAY Google Chrome Windows
          13 octubre 2010 at 21:28 #

          Racman disculpa que tarde en responderte, estoy muy ocupado con cosas del trabajo.

          Por lo que veo en tu SP recibes 2 parámetros y 1 es de salida, para invocarlo debes enviarles ambos parámetros aunque no hagas nada dentro del SP con el parámetro de salida, así como lo hiciste con tu código TSQL.
          Desde C# puedes hacer lo siguiente:

          1
          
          int salida = Convert.ToInt32(Conexion.GDatos.TraerValorEscalar("CalcTasa", "Entrada", DBNull.Value));

          o pasale otro valor si lo necesitas.

        • racman COLOMBIA Internet Explorer Windows
          14 octubre 2010 at 17:50 #

          No te preocupes por la demora GeekZero, pienso q todos debemos estar agradecidos por compartir tu conodimiento.
          hice la prueba como tu me recomendaste y me retorna cero, adjunto un ejemplo de la forma como lo trabajo siempre, pues de pronto es q no me he hecho entender… y pues la verdad me llama la atención la forma como invocas los procedimientos pues ahorra la escritura de mucho codigo..
          este es la forma como invoco el sp

          SqlConnection conn = new SqlConnection();
          conn = ObtenetConexionSQL(false);
          SqlCommand comando = new SqlCommand();
          comando.CommandType = CommandType.StoredProcedure;
          comando.CommandText = “CalcConsec”;
          comando.Connection = conn;
          comando.Parameters.AddWithValue(“@ConsecNombre”, “test”);
          comando.Parameters.Add(“@Consecutivo”, SqlDbType.Int);
          comando.Parameters["@Consecutivo"].Direction = ParameterDirection.Output;
          comando.ExecuteNonQuery();

          int salida = Convert.ToInt16(comando.Parameters["@Consecutivo"].Value);
          MessageBox.Show(salida.ToString());

  16. Adis BOLIVIA Mozilla Firefox Windows
    30 septiembre 2010 at 02:23 #

    Primeramente muchas gracias por el aporte… esta genial… pero como de costumbre la conexion es SQLServer… estoy tratando de empezar a explorar bases de datos libres para ser mas concreto MySql… entiendo que habria que agregar un clase MySql.cs con todas sus caracteristicas… pero como ya lo dije estoy empezando… te pediria el favor de que subas la clase respectiva para el MySql y tambien.. que es lo que cambia en la clase Conexion para conectarse a ella… o bien porfavor me lo pasas a mi correo adisbravo@hotmail.com

    Saludos y Bendiciones…!!!!

    • GeekZero PARAGUAY Google Chrome Windows
      30 septiembre 2010 at 18:32 #

      Fijate que esta colgado un ejemplo con Firebird, a partir de FB y MsSQL podras crear tu propia clase para MySQL :D , exitos..

      • Adis BOLIVIA Mozilla Firefox Windows
        2 octubre 2010 at 17:46 #

        Muy bien.. acabo de terminar la clase para un servidor MySql… si la necesitan o quieren mirarla.. la pueden bajar desde este enlace… http://www.gigasize.com/get.php?d=y1qqmytgzvf
        Una cosa mas… para que se conecten… necesitan cambiar la clase conexion este codigo:
        GDatos = new SqlServer(nombreServidor, baseDatos, usuario, password);
        por este otro:
        GDatos = new MySqlServer(nombreServidor, baseDatos, usuario, password);

        Espero aporte un poquito con esto… de verdad que me ha servido de mucho este post… mi agradecimiento nuevamente a el o los impulsores…!!!

        • GeekZero PARAGUAY Google Chrome Windows
          2 octubre 2010 at 20:41 #

          Excelente Adis, lo haz logrado :D fue sencillo no? Gracias por compartir lo que haz hecho con el resto de los lectores..

  17. racman COLOMBIA Internet Explorer Windows
    16 septiembre 2010 at 16:45 #

    Excelente codigo, gracias…

    tengo una dudo, aca cuando cambio de servidor pues simplemente hago el cambio en al linea de codigo
    AccesoDatos.Conexion.IniciarSesion(“127.0.0.1″, “Queryable”, “sa”, “***”);

    pero es necesario modificar el codigo, para el caso que tenga mi ejecutable final, y por ejemplo mi cliente cambie de servidor como puedo hacer esto, sin modificar el codigo… he leido algo q debo manejar un archivo de configuiracion pero la verdad no se como se maneja asi, gracias

    • GeekZero PARAGUAY Google Chrome Windows
      16 septiembre 2010 at 21:44 #

      Hola Racman, esto lo puedes resolver de muchas maneras, pero la que tu mencionas puedes configurarlo asi:

      1. Das clic derecho sobre tu proyecto, propiedades, en la lengueta de configuración agregas un recurso llamado Host con el valor 192.145.33.21 y otro BaseDato con valor DBtroce como ejemplos.
      2. Para consultar esos valores:

      1
      
      AccesoDatos.Conexion.IniciarSesion(Properties.Settings.Default.Host, Properties.Settings.Default.BaseDato, txtUsuario.Text, txtPassword.Text);

      A tu usuario y pass dejalo cargar al user, mejor si ellos se loguean con usuarios de la BD y no de tablas, solo que deberas administrar como dios manda tu motor..

  18. william PERU Mozilla Firefox Windows
    11 septiembre 2010 at 00:21 #

    hola amigo estoy intentando descargar el ejemplo que has subido al internet desde el link que indicas pero resulta que el link no existe porfavor haber si lo subes denuevo o me lo podrias enviar a mi correo valdezalva@hotmail.com .
    Muchas gracias!!

    • GeekZero PARAGUAY Google Chrome Windows
      11 septiembre 2010 at 09:50 #

      Ya está nuevamente en línea, justo lo intentaste cuando los servidores estaban en mantenimiento nada más, pruebalo nuevamente :)

  19. Francisco ARGENTINA Google Chrome Windows
    30 agosto 2010 at 10:52 #

    Hola que tal, muy buen articulo, realmente estaba buscando algo de practica, una consulta, éste proyecto puede ser adaptado para que haga uso de LinqToSql en plataforma web? Gracias.

    • GeekZero PARAGUAY Mozilla Firefox Windows
      30 agosto 2010 at 11:21 #

      Hola Francisco, con respecto a tu pregunta, puedes crear un proyecto en capas con LinqToSql (un conocido mío lo está haciendo) pero vas a escribir todo de nuevo, éstas líneas no te servirán, pero para inspiración es posible que si.

  20. lordfasd PERU Internet Explorer Windows
    17 agosto 2010 at 21:35 #

    Muy bueno ,yo tambiem hize uno pero aun me falta algo de codigo sql ;esto es
    por que me estoy iniciando en la programacion

  21. JR MEXICO Mozilla Firefox Windows
    6 agosto 2010 at 08:27 #

    Perfecto. ya quedo

    solo hacia falta agregar el alias de la DB en el archivo alias

    ya se logro la conexion a la base de datos.

    voy a revisar el proyecto.

    gracias de nueva cuenta

  22. JR MEXICO Mozilla Firefox Windows
    6 agosto 2010 at 07:11 #

    Ya descompacte el archivo en una carpeta del disco duro

    (d:proyectodevtroce)

    abro el proyecto, ejecuto y al intentar conectar me muestra una ventana con el siguiente mensaje

    I/O error file "Devtroce"

    Error while trying to open file

    revisando el codigo veo que el error se esta dando en la siguiente linea de codigo

    AccesoDatos.Conexion.IniciarSesion("127.0.0.1","Devtroce","SYSDBA","masterkey");

    que estoy omitiendo?

    • Orland PARAGUAY Mozilla Firefox Windows
      6 agosto 2010 at 07:46 #

      ¬¬

      Hola JR

      Notaste que no tenes la DB "Devtroce" ??

      Si GeeZero te la paso en link de Descarga lo mas seguro es que falte

      configurar el aliases.conf con la ruta donde se encuentra la DB.

      En tu caso seria algo asi

      – Dentro del aliases.conf –

      'Devtroce = D:proyectodevtroceDevtroce.FDB'

    • GeekZero PARAGUAY Google Chrome Windows
      6 agosto 2010 at 07:50 #

      Efectivamente es como te comenta Orland, necesitas tener instalado el Firebird y su servicio debe estar arriba, además de configurar el aliases.conf como lo indicaba.

      La BD lo coloque dentro del proyecto AccesoDatos, en la carpeta data, copialo donde quieras y asignale ese path al aliases

  23. GeekZero URUGUAY Google Chrome Windows
    5 agosto 2010 at 11:49 #

    Del apuro me he olvidado eso, el pass es

    1
    
    • onasis UNITED STATES Google Chrome Windows
      11 septiembre 2010 at 12:43 #

      Cordial saludo,
      me podrias indicar cual es el password de este archivo que hace referencia a un ejemplo donde utilizas como motor de base de datos a Firebird

      Descargalo de aqui: http://www.gigasize.com/get.php?d=0r5slgvb2zb

      habiar colocado esto pero no entiendo cual es el password

      5 Agosto 2010 en 11:49
      Del apuro me he olvidado eso, el pass es <pre lang="devtroce"&gt ;www.devtroce.com

      • GeekZero PARAGUAY Google Chrome Windows
        11 septiembre 2010 at 15:11 #

        Correjido el bug, también esta en el post el password..

        • onasis UNITED STATES Google Chrome Windows
          11 septiembre 2010 at 19:02 #

          Muchas gracias por tu ayuda

  24. JR MEXICO Mozilla Firefox Windows
    5 agosto 2010 at 08:43 #

    Excelente, muy rapida atencion.

    Mira, estoy iniciando un proyecto donde la base de datos esta en Firebird, y debo de realizarlo en un proyecto de 3 capas. pero desafortunadmente no logro echarlo a andar. y al llegar a este portal en encontre esta infromacion que es de de gran ayuda.

    De ser posible que tengas algun codigo para implementar lo de las 3 capas para una base de datos firebird, seria formidable.

    el tipo de aplicacion debe de ser de escritorio, base de datos en firebird y programacion en C# o Vb.Net, cualquier ayuda es bienvenida.

    La idea de tener en algun archivo descargable el proyecto que expones en este portal, es verlo funcionando con una base de datos SQLServer, pero el objetivo final es crear un nuevo proyecto para poder utilizarla en una base de datos firebird.

    Gracias, por la atencion al mensaje enviado.

    • GeekZero URUGUAY Google Chrome Windows
      5 agosto 2010 at 10:33 #

      Fijate JR, te he puesto un ejemplo Desktop ya con la clase editada para funcionar con Firebird, como dije en el post, ya incluye una copia de la BD que use y el Data Provider.

      Disculpa que he hecho un ejemplo algo chapucero, no está muy bien diseñada la interfaz, y no tiene casi comentarios, pero creo que es suficiente para comprender el concepto.

      Descargalo de aqui: http://www.gigasize.com/get.php?d=0r5slgvb2zb

      Lo he puesto en este servidor para no usar el ancho de banda innecesariamente y así llevar un registro de las descargas del ejemplo también :)

      Cuentanos que tal te va!

      • JR MEXICO Internet Explorer Windows
        5 agosto 2010 at 11:45 #

        Gracias por la ayuda. he descargado el archivo.

        tiene contraseña el archivo compactado, no puedo descompactarlo.

        Saludos, y gracias de nuevo.

  25. JR MEXICO Internet Explorer Windows
    5 agosto 2010 at 07:47 #

    Excelente codigo, de gran ayuda.

    Pero no logro poner todo el codigo en un proyecto para trabajar con el.

    No podrias por favor poner el proyecto en algun archivo compactado para poderlo descargar y ver como deberia de estar el proyecto?

    • GeekZero PARAGUAY Google Chrome Windows
      5 agosto 2010 at 07:55 #

      Que tal JR, normalmente debes ponerlo en un proyecto por separado dentro de la misma solucion, pero puedes hacerlo tambien dentro del mismo proyecto si sabes que usarás uno solo. Realmente a este codigo yo le he agregado más variantes tambien, para que plataforma quieres? WEB o Desktop? en el caso de WEB lo he cambiado en partes importantes para hacer uso de variables de SESSION en las capas de acceso a datos.. Si me pasas esta info puedo subirte un ejemplo apenas tenga tiempo para armarte uno..

Trackbacks/Pingbacks

  1. Como programar en n-Capas con C# – SQL Server (Parte 2) | DevTroce.com WordPress - 15 agosto 2010

    [...] Parte 1 |Parte 3 | Parte 4 | Parte 5 [...]

  2. Tweets that mention Programación en 3 Capas con C# - Parte 5 | DevTroce.com -- Topsy.com UNITED STATES - 14 julio 2010

    [...] This post was mentioned on Twitter by Ronald Riveros, DevTroce. DevTroce said: Como programar en n-Capas con C# (Parte 5): Con ésta entrega cumpliremos con la capa de… http://goo.gl/fb/MgTRa [...]

Responder