Beruflich Dokumente
Kultur Dokumente
2.
Capa de Negocio. Esta capa es la que sostiene todo el negocio de la aplicacin, es decir, todos
los clculos necesarios para que nuestra aplicacin haga lo que se espera de ella.
3.
Capa de Presentacin Esta capa comprende todo lo que se muestra hacia el usuario final, es decir, el
diseo de los formularios o plantillas con las que va a trabajar el usuario final.
Es importante separar bien estas capas, ya que por ejemplo el Negocio no podra tener acceso directamente sin
pasar primero por la capa Acceso a Datos, al igual que la capa presentacin no puede hacer ningn tipo de clculo
importante de la aplicacin o acceder directamente a Base de Datos.
vez
Abrimos
que
hemos
nuestro
Archivo->Nuevo Proyecto
entendido
Visual
como
Studio
funciona
2008
la programacin en
y
creamos
capas,
vamos
una solucin.
llevarlo
Para
cabo.
ello:
En Tipos de Proyecto seleccionamos "Soluciones de Visual Studio", ponemos un nombre a la solucin y elegimos
una ubicacin donde queremos guardar la solucin.
Ahora en el explorador de soluciones pinchamos con el botn derecho sobre la solucin y aadimos un nuevo
proyecto.
En tipos de proyecto elegimos un proyecto de tipo Visual Basic - Windows - Biblioteca de clases y le ponemos el
nombre AccesoDatos. Este proyecto corresponder a la Capa de Datos que hemos explicado anteriormente.
Nos os preocupis si solo os aparece en el explorador de proyectos el proyecto AccesoDatos, esto es normal.
Vamos aadir ahora un segundo proyecto del mismo tipo que el anterior llamado Negocio, para ello nos vamos
al Men "Archivo-Agregar-Nuevo Proyecto".
Si todo ha ido bien, el explorador de soluciones os debe de quedar de la siguiente manera:
Como podis ver ha vuelto a aparecer "SolucionCapas" englobando a los dos proyectos. Este segundo proyecto es
el que englobara toda la lgica del negocio de nuestra aplicacin.
Por ultimo vamos a crear un tercer proyecto que se corresponder con la capa de presentacin Para ello,
realizamos los mismos pasos anteriores para aadir un proyecto nuevo a la solucin.
En este caso elegimos un tipo de proyecto VisualStudio - Windows - Aplicacion de Windows Form y le damos el
nombre "Presentacion".
Si todo ha ido bien, el explorador de soluciones debe quedar de la misma forma que la imagen anterior.
Aqu podemos ver como exactamente como queda separadas cada capa.
Para ello debemos entender que el proyecto de presentacion "depende" directamente del proyecto de negocio y
este a su vez depende del proyecto de Acceso a Datos. Para decirle esto a Visual Studio pinchamos con el boton
derecho sobre el proyecto de presentacion y en el menu resultante pinchamos sobre "Dependencias del proyecto",
la ventana resultante
Como podemos ver tenemos que marcar solamente el proyecto "Negocio" de nuestra solucin Acceso a Datos no
lo marcamos pues el flujo de datos debe de pasar antes por el proyecto Negocio. Esto nos ayudara luego a
importar los proyectos entre ellos.
Hacemos la misma operacin con el proyecto Negocio aadiendo la dependencia del proyecto "AccesoDatos".
As
mismo
hay
que
aadir
directamente
las
referencias
de
cada
proyecto.
Si nos vamos al "My Project" del proyecto Presentacion y seleccionamos la pestaa Referencias se nos mostrara
una ventana con todas las referencias asociadas al proyecto, como podeis ver, aunque hemos asignado la
dependencia del proyecto Negocio no tenemos asignada la referencia.
Para ello pulsamos sobre el botn Agregar y seleccionamos en la ventana emergente la pestaa "Proyectos".
Seleccionamos la referencia del proyecto Negocio y pulsamos Aceptar. La referencia se ha aadido.
Hacemos la misma operacin con el MY PROJECT de Negocio y le aadimos la referencia del proyecto AccesoDatos.
De esta forma ya tendremos aadidas las referencias y dependencias entre proyectos de la solucion.
Nota:
Mas adelante os enseare otra forma de meter referencias entre proyectos. Veremos que podemos crear una dll
de un proyecto de una solucion en otra solucion como referencia.
2. Proyecto AccesoDatos
Vamos a empezar primero con el proyecto de Acceso a Datos, puesto que es el proyecto del que dependen los
dems proyectos y sobre el cual va a caer la responsabilidad de conectar y comunicarse directamente con la Base
de
Datos
de
nuestra
aplicacin.
Si nuestra aplicacin no comunicara con una base de datos este proyecto no tendra ningn sentido.
La idea de este proyecto es que sea capaz de conectar con cualquier tipo de base de datos, independientemente
de la cadena de conexin o a travs de un ODBC, por qu? la respuesta es sencilla, este proyecto debe ser comn
para
cualquier
Para
ello
tipo
de
crearemos
aplicacin
dos
que
clases
creemos
en
en
nuestro
el
futuro.
proyecto:
BaseDa
tos. Donde recaera todo el peso del proyecto.
BaseDa
tosException. Encargada de transmitir mensajes de errores a los dems proyectos.
En los siguientes captulos explicaremos que propiedades tendrn cada una de estas clases.
1
2
3
4
5
Option Explicit On
Imports System.Data.Common
Public Class BaseDatos
6
7
8
9
10
11
12
13
14
15
16
17
18
End Class
Notas:
Option Explicit ON hay que meterlo al principio de cualquier clase que creemos. Esto es para que no nos
permita crear variables sin definir el tipo, pues puede crear errores de compilacion.
El tipo Enumerado nos servira para identificar el tipo de conexion a la Base de Datos.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Me._Factory = DbProviderFactories.GetFactory(proveedor)
pParametros = Nothing
Catch ex As Exception
Throw New BaseDatosException("ERROR :" &
BASEDATOS.New(Parametros) ", ex)
End Try
End Sub
2. Constructor con parametros establecidos en el app.config del programa, el pasamos la key del proveedor y la
key de la Base de Datos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Catch ex As ConfigurationErrorsException
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.New(tipoConexion,CadenaConexion) ", ex)
End Try
End Sub
2
3
4
5
Exit Sub
7
8
9
10
11
End If
End If
12
13
14
15
End Select
16
17
Me.Conexion = _Factory.CreateConnection()
18
Me.Conexion.ConnectionString = Me.sCadenaConexion
19
End If
20
Me.Conexion.Open()
21
22
23
24
25
26
27
Catch ex As Exception
Throw New BaseDatosException("ERROR :" & ex.Message & " - Cadena conexion : " &
BASEDATOS.Conectar ", ex)
28
End Try
29
30
End Sub
En esta funcin se ve claramente el flujo de los datos, primero preguntamos si la conexin esta ya abierta, si no es
asi y es una nueva conexin entonces creamos la conexin en funcin del proveedor y cadena de conexin del
constructor
elegido.
Una vez que hayamos terminado con las operaciones contra la base de datos, debemos de utilizar una funcin que
nos desconecte de la sesin, porque si no esta conexin puede penalizar con el tiempo el rendimiento de la Base
de
Datos.
2
Try
If Me.Conexion.State.Equals(ConnectionState.Open) Then
Me.Conexion.Close()
Me.Conexion = Nothing
End If
Catch ex As DataException
8
9
10
Me.Conexion = Nothing
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.DESCONECTAR ", ex)
Catch ex As InvalidOperationException
11
Me.Conexion = Nothing
12
13
14
End Try
15
End Sub
El funcionamiento es sencillo, preguntamos si la conexion esta abierta, la cerramos y controlamos los errores.
Nota: El control de errores los veremos en siguientes captulos.
Como sabeis en base de datos las transacciones tiene muy buen uso, pues te permite hacer todo tipo de pruebas a
las base de datos y poder "retroceder" si algo ha salido mal. Hay 3 tipos de transacciones:
1.
BeginTrans. Es cuando empieza la transaccion. Todo lo que este despues de aqui se ejecutara en modo de
prueba.
2.
Commit. Si todo lo que hemos programado ha salido correcto y no ha habido errores debemos de lanzar
este comando a la Base de Datos, que hara que los cambios tengan efecto.
3.
RollBack. Si se produce un error durante la ejecucion debemos de lanzar este comando a la Base de Datos,
de tal forma que todos los cambios producidos en base de datos desde el BeginTrans no tengan efecto.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Ahora vamos a ver como podemos hacer consultas a la base de datos (inserciones, modificaciones, eliminaciones o
consultas
para
traernos
Primero vamos a ver como ejecutar consultas para inserciones, modificaciones o eliminaciones:
?
1
2
Me.CrearComando(CadenaSql, "S")
Me.EjecutarComando()
EjecutarConsulta = True
6
7
8
9
10
Catch ex As Exception
EjecutarConsulta = False
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.EjecutarConsulta ", ex)
End Try
End Function
datos).
Esta
funcion
crea
un
comando
que
ejecutara
la
consulta
en
la
Base
2
3
4
5
Try
Select Case tipoBBDD
Case BBDD.SQL : Me.Commando = New SqlCommand
7
8
9
10
11
12
13
Me.Commando = _Factory.CreateCommand()
Me.Commando.Connection = Me.Conexion
Me.Commando.CommandTimeout = 99999999
Select Case TipoConsulta
14
15
Me.Commando.CommandType = CommandType.StoredProcedure
16
17
Case "T"
18
Me.Commando.CommandType = CommandType.TableDirect
19
Case Else 'Sentencia SQL
20
Me.Commando.CommandType = CommandType.Text
21
22
End Select
23
24
Me.Commando.CommandText = CadenaSql
25
26
27
28
29
30
31
32
Catch ex As Exception
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.CrearComando ", ex)
End Try
de
Datos.
33
34
35
End Sub
1
2
3
4
5
6
Catch ex As Exception
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.EjecutarComando ", ex)
End Try
7
8
End Sub
Si lo que queremos es hacer consultas para recuperar datos de la base de datos y tratarlos luego en nuestro
programa tenemos varias opciones, podemos traernos en un DATAREADER, DATATABLE o en un DATASET. A mi me
gusta mas recuperarlo en un DATATABLE pues a mi parecer es mas fcil tratar despues los datos.
Para poder utilizar las siguientes funciones debemos primero crear esta funcion, que dependiendo del tipo de Base
de Datos que tengamos ejecutara la consulta de una manera o de otra.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
End Function
La siguiente funcion ejecuta una consulta (CadenaSQL) y devuelve el resultado en un DATATABLE (Tabla) que
luego podemos tratar en la capa de NEGOCIO. TipoConsulta nos dice si se trata de una consulta o de un
procedimiento Almacenado y con "HayParametros" le decimos si le pasamos parametros (solo en el caso de que
estemos tratando con un procedimiento almacenado.
?
5
6
7
8
9
10
11
12
Try
13
14
15
16
17
18
CrearComando(CadenaSQL, TipoConsulta)
19
20
If HayParametros Then
21
22
Me.Commando.Parameters.Add(pParametros(i))
23
i = i + 1
End While
24
25
End If
26
27
28
29
30
31
32
33
arsDatos = Me.EjecutarConsultaDataAdapter()
arsDatos.Fill(datos)
Tabla = datos.Tables(0)
34
Dame_Datos_DT = False
35
End If
36
37
Catch ex As Exception
38
39
40
41
42
Dame_Datos_DT = False
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.DameDatosDT ", ex)
End Try
End Function
La siguiente funcion Ejecuta una consulta (CadenaSQL) y devuelve los datos en un DATAADAPTER que luego
podremos utilizar en la capa NEGOCIO.
?
4
5
Try
Dim i As Integer = 0
6
7
CrearComando(CadenaSQL, TipoConsulta)
8
9
If HayParametros Then
While i <= UBound(pParametros)
10
Me.Commando.Parameters.Add(pParametros(i))
11
i = i + 1
12
End While
13
14
15
16
17
18
19
20
21
22
End If
Return Me.EjecutarConsultaDataAdapter()
Catch ex As Exception
Dame_Datos_DA = Nothing
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.DameDatos_DA ", ex)
End Try
End Function
La siguiente funcion ejecuta una consulta (CadenaSQL) y devuelve los datos en un DATAREADER que luego
podremos utilizar en la capa de NEGOCIO.
?
Try
Dim i As Integer = 0
CrearComando(CadenaSQL, TipoConsulta)
If HayParametros Then
While i <= UBound(pParametros)
Me.Commando.Parameters.Add(pParametros(i))
i = i + 1
10
End While
11
End If
12
13
Return Me.Commando.ExecuteReader()
14
15
Catch ex As Exception
16
17
18
19
20
Return Nothing
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.DameDatosDR ", ex)
End Try
End Function
Nota: "HayParametros" le dice a la base de datos que el procedimiento almacenado lleva parametros. Para poder
pasar parametros debemos de utilizar la siguiente funcion:
?
Try
6
7
8
9
10
11
Case BBDD.ODBC
12
13
Case BBDD.OLEDB
14
15
16
17
pParametros(Indice).ParameterName = Nombre
18
19
20
21
pParametros(Indice).DbType = DbType.Int64
22
23
pParametros(Indice).DbType = DbType.Double
24
25
26
pParametros(Indice).DbType = DbType.Decimal
27
28
pParametros(Indice).DbType = DbType.DateTime
29
30
pParametros(Indice).DbType = DbType.String
31
32
pParametros(Indice).DbType = DbType.Int32
33
34
35
pParametros(Indice).DbType = DbType.Int16
End Select
36
37
pParametros(Indice).Value = Valor
38
Aadir_Parametro = True
39
40
41
42
Catch ex As Exception
Aadir_Parametro = False
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.Aadir_Parametro ", ex)
End Try
43
44
45
End Function
Esta funcion debemos de llamarla antes que la funcion para devolver los datos de Base de Datos.
Ejemplo:
Datos.CGPO.Aadir_Parametro(0,
"CodigoCliente",
Datos.CGPO.Dame_Datos_DT("pa_DameDatosCliente",
"I",
True,
125)
TCliente,
"P")
Aqui le estamos diciendo que le pasamos un parametro a la base de datos llamado "CodigoCliente" de tipo Entero
"I" con valor 125 en el indice 0. Luego llamamos al procedimiento Almacenado "pa_DameDatosCliente", le
decimos que tiene parametros y devolvemos los datos en un DATATABLE llamado TCliente. La "P" indica
Procedimiento almacenado, para ver todos los tipos de consulta podeis ver la funcion CrearComando.
Para los que no sepais que es un procedimiento almacenado o PA, segun la definicion encontrada en la wikipedia:
"Un procedimiento
almacenado fsicamente en una base de datos. Su implementacin vara de un gestor de bases de datos a otro. La
ventaja de un procedimiento almacenado es que al ser ejecutado, en respuesta a una peticin de usuario, es
ejecutado directamente en el motor de bases de datos"
Es decir, sirver para hacer que las consultas a base de datos sean mas rapidas que una consulta normal, ya que
esta
directamente
conectado
con
la
base
de
datos.
Asi que nuestra clase tambien debe de tener una funcion que sea capaz de ejecutar un PA alojado en la base de
datos
que
Para
ello
estamos
utilizamos
la
conectada.
siguiente
2
3
4
5
6
7
CrearComando(NombreProcedimiento, "P")
If HayParametros Then
10
Me.Commando.Parameters.Add(pParametros(i))
11
i = i + 1
funcion:
12
End While
13
End If
14
If Me.Commando.ExecuteNonQuery() = 0 Then
15
Ejecutar_PA = False
16
Else
17
Ejecutar_PA = True
18
End If
19
20
Catch ex As Exception
21
22
23
Ejecutar_PA = False
Throw New BaseDatosException("ERROR :" & ex.Message & "
BASEDATOS.EjecutarPA ", ex)
24
End Try
25
End Function
26
Lo unico que le pasamos a la funcion es el nombre del procedimiento y si le hemos pasado parametros antes de la
llamada, recordad que teneis que pasarselo antes de la llamada con la funcion AadirParametro.
Como habeis podido observar mientras hemos ido construyendo la clase BaseDatos el compilador habr
reconocido errores en la parte del catch ya que no reconocia la clase que vamos a implementar a continuacin. Se
trata de la clase BaseDatosException, la cual, como su nombre indica va ha controlar las excepciones producidas
durante el uso de la clase. Esto nos permitira controlar las excepciones y traspasar el mensaje de error entre las
capas de nuestra aplicacin, es decir, que podremos saber que error se ha producido en la capa de AccesoDatos
desde
la
capa
Negocio
luego
en
Presentacion,
asi
mostrarla
al
usuario
final.
Para ello nos vamos al Proyecto AccesoDatos y aadimos una nueva clase llamada: BaseDatosException e
implementamos el siguiente codigo:
?
Option Explicit On
2
3
4
5
6
7
End Sub
9
10
11
12
13
14
End Class