Documentos de Académico
Documentos de Profesional
Documentos de Cultura
#endregion
Lo siguiente por hacer es muy sencillo, crear los setters y getters de nuestros atributos anteriormente definidos:
1 #region "Setters y Getters"
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
Creamos ahora los mtodos para hacer lecturas a la fuente de datos, lo hacemos ya en esta clase porque son metodos
generales que pueden implementar tal cual las clases hijas. En el caso de los DataReader que son muy especificos del
driver utilizados, vamos a utilizar el objeto IDataReader que es una interfaz de implementacin general.
1
2
3
4
5
6
7
8
#region "Lecturas"
// Obtiene un DataSet a partir de un Procedimiento Almacenado.
public DataSet TraerDataSet(string procedimientoAlmacenado)
{
var mDataSet = new DataSet();
CrearDataAdapter(procedimientoAlmacenado).Fill(mDataSet);
return mDataSet;
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
} // end TraerDataset
//Obtiene un DataSet a partir de un Procedimiento Almacenado y sus parmetros.
public DataSet TraerDataSet(string procedimientoAlmacenado, params Object[] args)
{
var mDataSet = new DataSet();
CrearDataAdapter(procedimientoAlmacenado, args).Fill(mDataSet);
return mDataSet;
} // end TraerDataset
// Obtiene un DataSet a partir de un Query Sql.
public DataSet TraerDataSetSql(string comandoSql)
{
var mDataSet = new DataSet();
CrearDataAdapterSql(comandoSql).Fill(mDataSet);
return mDataSet;
} // end TraerDataSetSql
// Obtiene un DataTable a partir de un Procedimiento Almacenado.
public DataTable TraerDataTable(string procedimientoAlmacenado)
{ return TraerDataSet(procedimientoAlmacenado).Tables[0].Copy(); } // end
TraerDataTable
//Obtiene un DataSet a partir de un Procedimiento Almacenado y sus parmetros.
public DataTable TraerDataTable(string procedimientoAlmacenado, params Object[] args)
{ return TraerDataSet(procedimientoAlmacenado, args).Tables[0].Copy(); } // end
TraerDataTable
//Obtiene un DataTable a partir de un Query SQL
public DataTable TraerDataTableSql(string comandoSql)
{ return TraerDataSetSql(comandoSql).Tables[0].Copy(); } // end TraerDataTableSql
// Obtiene un DataReader a partir de un Procedimiento Almacenado.
public IDataReader TraerDataReader(string procedimientoAlmacenado)
{
var com = Comando(procedimientoAlmacenado);
return com.ExecuteReader();
} // end TraerDataReader
// Obtiene un DataReader a partir de un Procedimiento Almacenado y sus parmetros.
public IDataReader TraerDataReader(string procedimientoAlmacenado, params object[]
args)
{
var com = Comando(procedimientoAlmacenado);
CargarParametros(com, args);
return com.ExecuteReader();
} // end TraerDataReader
// Obtiene un DataReader a partir de un Procedimiento Almacenado.
public IDataReader TraerDataReaderSql(string comandoSql)
{
var com = ComandoSql(comandoSql);
return com.ExecuteReader();
} // end TraerDataReaderSql
// Obtiene un Valor Escalar a partir de un Procedimiento Almacenado. Solo funciona con
SP's que tengan
// definida variables de tipo output, para funciones escalares mas abajo se declara un
metodo
public object TraerValorOutput(string procedimientoAlmacenado)
{
// asignar el string sql al command
var com = Comando(procedimientoAlmacenado);
// ejecutar el command
com.ExecuteNonQuery();
// declarar variable de retorno
Object resp = null;
// recorrer los parametros del SP
foreach (IDbDataParameter par in com.Parameters)
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#endregion
El siguiente bloque es para ejecutar procesos que no devuelven valores, al inicio tendremos varios mtodos abstractos,
para que las clases derivadas estn obligadas a implementarlas a su manera, en un modo especifico, ya que los objetos
connection, command, dataadapter, son muy especficos y deben ser implementados por cada 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
55
56
57
58
59
60
61
62
#region "Acciones"
protected abstract
protected abstract
protected abstract
protected abstract
Object[] args);
protected abstract
protected abstract
// cerrar conexion
public void CerrarConexion()
{
if (Conexion.State != ConnectionState.Closed)
MConexion.Close();
}
// end CerrarConexion
63 } // end Ejecutar
#endregion
Ahora bien, no podemos olvidarnos de la seccin transaccional, no se utiliza normalmente en todos lados desde la
aplicacin, pero en procesos dependientes es necesario, as que si necesitamos usarlo, podemos crearlo de este modo:
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
#region "Transacciones"
protected IDbTransaction MTransaccion;
protected bool EnTransaccion;
//Comienza una Transaccin en la base en uso.
public void IniciarTransaccion()
{
try
{
MTransaccion = Conexion.BeginTransaction();
EnTransaccion = true;
}// end try
finally
{ EnTransaccion = false; }
}// end IniciarTransaccion
using System;
using System.Data;
namespace AccesoDatos
{
public abstract class GDatos
{
#region "Declaracin de Variables"
protected
protected
protected
protected
protected
string
string
string
string
string
MServidor = "";
MBase = "";
MUsuario = "";
MPassword = "";
MCadenaConexion = "";
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
return mDataSet;
} // end TraerDataset
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#endregion
}// end class gDatos
}// end namespace
Nota: visto que el post, se est quedando muy largo, lo separar en partes e ir agrengando de a poco las otras clases y
luego las otras capas lgicas.
El primer mtodo que tendr esta clase, es un mtodo sellado que sobreescibir el de su padre, y crear el
ConnectionString y lo retornor.
public override sealed string CadenaConexion
1
{
2
get
3
{
4
if (MCadenaConexion.Length == 0)
5
{
6
if (MBase.Length != 0 && MServidor.Length != 0)
7
{
8
var sCadena = new System.Text.StringBuilder("");
9
sCadena.Append("data source=;");
10
sCadena.Append("initial catalog=;");
11
sCadena.Append("user id=;");
12
sCadena.Append("password=;");
13
sCadena.Append("persist security info=True;");
14
sCadena.Replace("", Servidor);
15
sCadena.Replace("", Base);
16
sCadena.Replace("", Usuario);
17
sCadena.Replace("", Password);
18
19
return sCadena.ToString();
20
}
21
throw new Exception("No se puede establecer la cadena de
22
conexin en la clase SQLServer");
23
}
24
return MCadenaConexion;
25
}// end get
26
set
27
{ MCadenaConexion = value; } // end set
28
}// end CadenaConexion
sta es una de las caracteristicas mas llamativas y tiles, que nos permitir cargar una cantidad n de parmetros,
a los SP que invocaremos
1 protected override void CargarParametros(System.Data.IDbCommand com, Object[] args)
2{
Ya en este punto si intentamos programar en capas, supongo que sabemos para que sirve un DataAdapter,
simplemente veremos como crearlo y asociarlo con el commando a su vez, este mtodo es para las llamadas a
Procedimientos
1
2
3
4
5
6
7
La siguiente es casi los mismo que la anterior, pero para ejecucin de querys SQL
Nada ms queda crear los constructores, creamos 4 sobrecargas del mismo segn lo que necesitemos ms
adelante.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public SqlServer()
{
Base = "";
Servidor = "";
Usuario = "";
Password = "";
}// end DatosSQLServer
public SqlServer(string cadenaConexion)
{ CadenaConexion = cadenaConexion; }// end DatosSQLServer
public SqlServer(string servidor, string @base)
{
Base = @base;
Servidor = servidor;
}// end DatosSQLServer
public SqlServer(string servidor, string @base, string usuario, string password)
{
Base = @base;
Servidor = servidor;
Usuario = usuario;
Password = password;
}// end DatosSQLServer
using System;
namespace AccesoDatos
{
public class SqlServer : GDatos
{
/*
* Continuaremos con el mtodo Comando, procediendo de igual forma que en los
anteriores.
* En este caso, adems, implementaremos un mecanismo de preservacin de los
Comandos creados,
* para acelerar su utilizacin. Esto es, cada procedimiento que sea accedido,
se guardar
* en memoria hasta que la instancia del objeto se destruya. Para ello,
declararemos una variable
* como HashTable para la clase, con el modificador Shared (compartida) que
permite
* persistir la misma entre creaciones de objetos
*/
static readonly System.Collections.Hashtable ColComandos = new
System.Collections.Hashtable();
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
10
{
var sCadena = new System.Text.StringBuilder("");
sCadena.Append("data source=<SERVIDOR>;");
sCadena.Append("initial catalog=<BASE>;");
sCadena.Append("user id=<USER>;");
sCadena.Append("password=<PASSWORD>;");
sCadena.Append("persist security info=True;");
sCadena.Append("user id=sa;packet size=4096");
sCadena.Replace("<SERVIDOR>", Servidor);
sCadena.Replace("<BASE>", Base);
sCadena.Replace("<USER>", Usuario);
sCadena.Replace("<PASSWORD>", Password);
return sCadena.ToString();
}
throw new Exception("No se puede establecer la cadena de conexin
en la clase DatosSQLServer");
}
return MCadenaConexion = CadenaConexion;
}// end get
set
{ MCadenaConexion = value; } // end set
}// end CadenaConexion
/*
* Agregue ahora la definicin del procedimiento CargarParametros, el cual
deber asignar cada valor
* al parmetro que corresponda (considerando que, en el caso de SQLServer,
el parameter 0
* siempre corresponde al return Value del Procedimiento Almacenado). Por
otra parte, en algunos casos,
* como la ejecucin de procedimientos almacenados que devuelven un valor como
parmetro de salida,
* la cantidad de elementos en el vector de argumentos, puede no corresponder
con la cantidad de parmetros.
* Por ello, se decide comparar el indicador con la cantidad de argumentos
recibidos, antes de asignar el valor.
* protected override void CargarParametros(System.Data.IDbCommand Com,
System.Object[] Args)
*/
protected override void CargarParametros(System.Data.IDbCommand com, Object[]
args)
{
for (int i = 1; i < com.Parameters.Count; i++)
{
var p = (System.Data.SqlClient.SqlParameter)com.Parameters[i];
p.Value = i <= args.Length ? args[i - 1] ?? DBNull.Value : null;
} // end for
} // end CargarParametros
/*
* En el procedimiento Comando, se buscar primero si ya existe el comando en
dicha Hashtable para retornarla
* (convertida en el tipo correcto). Caso contrario, se proceder a la
creacin del mismo,
* y su agregado en el repositorio. Dado que cabe la posibilidad de que ya
estemos dentro de una transaccin,
* es necesario abrir una segunda conexin a la base de datos, para obtener la
definicin de los parmetros
* del procedimiento Almacenado (caso contrario da error, por intentar leer
sin tener asignado el
* objeto Transaction correspondiente). Adems, el comando, obtenido por
cualquiera de los mecanismos
* debe recibir la conexin y la transaccin correspondientes (si no hay
Transaccin, la variable es null,
* y ese es el valor que se le pasa al objeto Command)
*/
0
10
1
10
2
10
3
10
4
10
5
10
6
10
7
10
8
10
9
11
0
11
1
11
2
11
3
11
4
11
5
11
6
11
7
11
8
11
9
12
0
12
1
12
2
12
3
12
4
12
5
12
6
12
7
12
8
12
9
13
0
13
1
13
2
13
3
13
4
13
/*
* Luego implementaremos CrearConexion, donde simplemente se devuelve una
nueva instancia del
* objeto Conexin de SqlClient, utilizando la cadena de conexin del objeto.
*/
protected override System.Data.IDbConnection CrearConexion(string
cadenaConexion)
{ return new System.Data.SqlClient.SqlConnection(cadenaConexion); }
1.
Marcelo
6 febrero 2013 at 16:42 #
El mejor artculo sobre programacin en capas en C# que he visto, til y muy didctico. Modifiqu el
cdigo de la clase SqlServer para acceder a Postgresql y funcion correctamente cuando implementas
query sql, pero siempre devuelve errores con procedimientos almacenados con parmetros. Es evidente
que Sql Server y Postgresql manejan esto de forma diferente, pero ya los solucion.
A continuacin transcribo el cdigo para trabajar con Postgresql (es necesario bajar el proveedor Npgsql
.)
Saludos
using System;
using System.Data;
using Npgsql;
using NpgsqlTypes;
namespace LsiDatos
{
public class ServidorPG : GDatos
{
static readonly System.Collections.Hashtable ColComandos = new System.Collections.Hashtable();
public override sealed string CadenaConexion
{
get
{
if (MCadenaConexion.Length == 0)
{
if (MBase.Length != 0 && MServidor.Length != 0)
{
var sCadena = new System.Text.StringBuilder();
sCadena.Append(Server=;);
sCadena.Append(Port=5432;);
sCadena.Append(User Id=;);
sCadena.Append(Password=;);
sCadena.Append(Database=;);
sCadena.Append(Encoding=UTF8);
sCadena.Replace(, Servidor);
sCadena.Replace(, Base);
sCadena.Replace(, Usuario);
sCadena.Replace(, Password);
return sCadena.ToString();
}
throw new Exception(No se pudo definir la cadena de conexin para la clase DatosPostgresql);
}
return MCadenaConexion = CadenaConexion;
}// end get
set
{ MCadenaConexion = value; } // end set
}// end CadenaConexion
protected override void CargarParametros(System.Data.IDbCommand com, Object[] args)
{
for (int i = 1; i <= com.Parameters.Count; i++)
{
var p = (Npgsql.NpgsqlParameter)com.Parameters[i -1];
p.Value = i <= args.Length ? args[i 1] ?? DBNull.Value : null;
} // end for
} // end CargarParametros
Para ello creamos un objeto esttico de la clase GDatos que instanciar de la clase SqlServer. Creo que ya van
captando el rumbo de esto no? si crearamos otra clase por ejemplo Oracle.cs o MySQL.cs, solamente
cambiariamos una linea de cdigo, donde el objeto GDatos del tipo GDatos, sea SqlServer, Oracle u otro
motor que codifiquemos. Podemos hacerlo con ODBC, OleDB para conexiones genricas. No les parece
grandioso que solo deban tocar parte de una lnea de cdigo para portar la App a cualquier otro motor de Base
de Datos?
namespace AccesoDatos
1
{
2
public class Conexion
3
{
4
public static GDatos GDatos;
5
public static bool IniciarSesion(string nombreServidor, string baseDatos,
6
string usuario, string password)
7
{
8
GDatos = new SqlServer(nombreServidor, baseDatos, usuario, password);
9
return GDatos.Autenticar();
10
} //fin inicializa sesion
11
12
public static void FinalizarSesion()
13
{
14
GDatos.CerrarConexion();
15
} //fin FinalizaSesion
16
17
}//end class util
18
}//end namespace
En la siguiente entrega veremos como crear la capa de Negocio y vincularla a estas capas de Acceso a Datos.
Preferentemente trabajaremos con procedimientos almacenados como Zeus manda. Para crear, listar y buscar
tendremos 3 distintos procedimientos.
1
2
3
4
5
6
7
8
1
2
3
4
5
1
2
3
4
5
Con esto ya tenemos creada la estructura de la base de datos completa, al menos hasta donde vamos a utilizar.
Estos SP, se pueden considerar parte de la capa de negocios, no precisamente siempre tiene que estar en la
aplicacin, es lo que vena escribiendo en las primeras partes del tutorial.
Del lado de la aplicacin utilizaremos el mapeo ORM (doy por sabido que conocen que esto, sino pueden
investigarlo aqu), ya que es una de la prcticas ms utilizadas y probadas que ahorran cdigo y ayudan a
cumplir con varios conceptos de la OOP. Dentro del mismo proyecto de biblioteca de clases, que estamos
teniendo en nuestra solucin (hasta ahora no hemos creado ningn tipo de interfaz de usuario). Creo
conveniente crear una carpeta en la raz del proyecto llamada Orm, justamente para seguir la convencin (trato
de seguirlas todas, derrepente se me escapa alguna, sabrn disculparme :S). Al crear esta carpeta, y crear clases
dentro de ella tambin se crear un nuevo nivel de espacios de nombres: AccesoDatos.Orm.
A esta la llamaremos Cliente.cs, y as una clase por cada tabla que tengamos en nuestra BBDD. En ella
crearemos 3 variables, que representarn los atributos de Cliente (mapeando los campos de la tabla). Al mismo
tiempo de crear estos, crearemos sus setters y getters.
Ahora es momento de utilizar el potencial del cdigo que hemos venido escribiendo, veanlo en accin en los 3
mtodos que crearemos, uno para dar de Alta, un registro de cliente, en la BBDD, otro para buscar, y otro para
listar todos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
En esta clase, deben crear todos los mtodos, que correspondan a la clase cliente. Pueden crear todos los que
quieran, sin importar que sta clase quede muy larga, simplemente deben encargarse, que sea aqu donde
corresponde una accin en s. Como ven estamos aplicando sobrecarga de mtodos en sta clase (no lo
confundan con polimorfismo).
La clase completa quedara 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
using System;
using System.Data;
namespace AccesoDatos.Orm
{
public class Cliente
{
// lista de atributos con setters y getters
public short IdCliente { get; set; }
public string Descripcion { get; set; }
public string Sigla { get; set; }
// mtodos
public void Crear(Cliente cliente)
{ Conexion.GDatos.Ejecutar("insCliente", cliente.IdCliente,
cliente.Descripcion, cliente.Sigla, 3); }
public DataTable Listar()
{ return Conexion.GDatos.TraerDataTable("slcCliente"); }
public Cliente Listar(int idCliente)
{
var cliente = new Cliente();
DataTable dt = Conexion.GDatos.TraerDataTable("slcClienteById", idCliente);
if (dt.Rows.Count > 0)
{
cliente.IdCliente = Convert.ToInt16(dt.Rows[0][0]);
cliente.Descripcion = Convert.ToString(dt.Rows[0][1]);
cliente.Sigla = Convert.ToString(dt.Rows[0][2]);
return cliente;
}
return null;
32
33
34
35
36
}
}
}
Con sto vemos como se implementa la capa de negocios. En la siguiente entrega veremos ya la capa de
Presentacin, en lo posible, utilizares todas las clases hechas ya incluida sta en una aplicacin WinForm y
otra WebForm, vern que no slo es portable a cualquier proveedor de datos, sino que es portable a distintas
plataformas de ejecucin.
Evidentemente, un sistema real no lo harn as, el botn 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 implementacin
interesante sera agregarle un identity a la tabla cliente, pero para el ejemplo ya servir esto. Para esto
crearemos 2 proyectos ms dentro de nuestra solucin, uno ser una aplicacin Windows Form con Visual C#,
y la otra un sitio Web.
El cdigo que pondremos en el botn 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 aplicacin, sino solo sus valores de conexin en memoria.
1 try
2{
3
4
5
6
7
8
9
}
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 mtodo crear enviandole el nuevo objeto cliente.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Luego de esto escribimos el cdigo de listado de todos los clientes, y lo cargamos en la grilla. Se dan cuenta
que necesitamos muy pocas lineas de cdigo en la capa de Presentacin, y que no tiene una dependencia
de la BBDD?. Si se dan cuenta, cuando vamos a devolver muchos registros no podemos utilizar un montn de
instancias de Cliente, sino simplemente devolvemos un DataTable, DataSet o DataReader.
1
2
3
4
5
6
7
8
9
Finalmente el cdigo de bsqueda quedara algo asi. Cmo sabemos que si buscamos por la PK, siempre nos
devolver un slo 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
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
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")); }
74
75
76
77
78
79
80
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Con respecto a la parte web, tendremos 2 partes, el cdigo 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
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
</html>
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"); }
}
70
71
72
73
74
75 }