Categorías
asp.net

Acceso a Bases de Datos – ADO.NET – Modo Desconectado, con ASP .Net y MVC4

Hasta el momento se ha empleado una conexión abierta hacia la base de datos para realizar las peticiones de consulta o actualización de información persistente, sin embargo un compañero comentó que sería bueno hacer hincapié en que, según la necesidad del cliente, se podría hacer uno de un “modo desconectado” de acceso a base de datos. Lo cual recuerda que sería bueno definir los conceptos de modo conectado y desconectado.

Pero… ¿A qué se refieren los desarrolladores con los términos conectado o desconectado?

La forma común y más fácil de implementar en el modo “conectado” o modo de trabajo en el cual el sistema abre una conexión, realiza una acción (o transacción) sobre la base de datos y al final cierra dicha conexión por lo cual los datos quedan persistentes inmediatamente. El modo desconectado sería lo equivalente a hacer una copia local de los objetos de la base de datos sobre las que se desea trabajar (realizando una única apertura inicial de la conexión a base de datos al inicio), para manipularlos con el número de transacciones que se desee y finalmente hacer un volcado del resultado sobre la base de datos, momento en el cual los cambios son recién persistentes.

Esquema del modo desconectado de acceso a BBDD

La pregunta que os surgirá en estos momentos, es ¿Cual es más eficiente? La respuesta es “Depende”.

Si se ha optado por un sistema en el que se va a manipular datos muy delicados y un cambio no registrado puede significar una gestión errónea en una transacción que se ejecute inmediatamente después de la primera, por lo que sería recomendable que dicha aplicación tenga un sistema conectado, ya que de esta manera en todo momento la comunicación con la base de datos y la información estará actualizada. Sin embargo esto va a producir un alto consumo de recursos (entre ellos, las aperturas y cierres de conexiones además de las operaciones de gestión interna del sistema gestor de base de datos) pero va evitar errores que podrían suponer graves consecuencia para el cliente. Por poner un ejemplo sencillo piénsese en un banco o tienda online donde un cambio en la cuenta puede afectar a las siguientes acciones disponibles, generando un error si no se actualizan los cambios inmediatamente.

Por otro lado, si el sistema en cuestión no requiere de una actualización continua de información  sería recomendable utilizar una conexión en modo desconectado, donde la información se carga al iniciar la aplicación y en la que se vaya refrescando cada determinado tiempo según el criterio que se crea conveniente. Este tipo de sistemas agota los recursos de una manera completamente distinta, ya que en un sistema conectado, solo tenemos que recuperar la información que no sea necesaria en ese momento, mientras que en este caso recuperaremos mucha información inicialmente, para poder cerrar la base de datos. Para citar un ejemplo se puede pensar en un volcado masivo entra bases de datos.

Se dice que el objeto DataReader realiza un modo conectado ya que necesita tener un curso abierto a la base de datos para poder operar sin embargo el DataSet se dice que es desconectado ya que este ejecuta carga los valores en memoria, desconecta y cuando se requiera se volverá a conectar para realizar un volcado de los datos contenidos en memoria en el soporte persistente de datos.

Elementos presentes en la base de datos

Por otro lado, si el desarrollador lo desea también podría servirse de ambas tecnologías para la consecución de sus fines, ya que puede usar en DataReader para leer y volcar los valores a objetos de clases personalizadas y luego desconectar, de la misma manera que lo hace DataAdapter, pero manualmente.

Ahora se mostrará cómo se haría un acceso a base de datos y manipulación por medio de un modo Desconectado.

Para empezar se definirá el controlador de la página es el siguiente:

Controlador de la vista ADO_Desconectado

A destacar que se utilizará el mismo código de vista que se ha utilizado en el post anterior, simplemente se cambiará el código del método utilizado en modelo, el cual será llamado getAllDataDesconectado

Codigo presente en el Modelo para la obtención de datos en modo desconectado.

Como se puede ver, el programador ha creado un DataSet en el que ha añadido una tabla llamada “Asistentes”. El DataAdapter llenará de datos al DataSet en su tabla Asistentes. Y posteriormente se leerán los datos del DataTable y se realizará la acción que más convenga, en este caso, guardarlos datos en una lista para devolvérsela al controlador.

Como paso final solo quedaría mostrar el resultado en la vista.

Ahora que ya se sabe hacer una consulta sobre la base de datos utilizando el modo desconectado, no es complicado hacer modificaciones o eliminaciones sobre los elementos del DataSet y así, al volcar los datos a la base de datos al final de la operación, modificar los elementos persistentes en la base de datos.

Categorías
asp.net

Error Number: 15382 al instalar DotNetNuke

Connection Error(s):
Index #: 0
Source: .Net SqlClient Data Provider
Class: 14
Number: 15382
Message:

Solución a este error

  • Seleccione el grupo de aplicaciones que carga el DotNetNuke
  • Boton derecho «Configuración avanzada«
  • En la sección «Modelo de proceso» poner a true «Cargar prefil de Usuario«.
Categorías
asp.net

¿Que son los archivos .dll?

Las .DLL son LIBRERIAS que contienen rutinas y funciones que utilizan los programas.

Las librerías se utilizan para evitar tener que escribir repetidamente en los ejecutables las mismas instrucciones.

Las librerías permiten, además, que el .EXE sea más pequeño y las rutinas solamente se cargan en memoria cuando son llamadas por el programa.

Después, con programas especiales, se las «compila» para que puedan funcionar.

Entonces se convierten a lenguaje binario que nadie va a poder entender.

La unica forma de verlas es con editores especiales pero, aún así, lo verás en hexadecimal.

Categorías
asp.net

Recorrer y modificar una Hashtable

Dim tablaPrueba As New Hashtable

tablaPrueba.Add(11, "Madrid")
tablaPrueba.Add(22, "Barcelona")
tablaPrueba.Add(3, "Valencia")
tablaPrueba.Add(44, "Bilbao")
tablaPrueba.Add(57, "Sevilla")

' Se crea un Array de elementos DictionaryEntry con el tamaño de la tabla a recorrer
 Dim arrayCopia(tablaPrueba.Count - 1) As DictionaryEntry

' Se copia el contenido de la tabla sobre el array que acabamos de crear
 tablaPrueba.CopyTo(arrayCopia, 0)

' Se borra completamente la tabla inicial
 tablaPrueba.clear

' Se recorre el arrayCopia con un bucle For... Next a la vez que se añaden los nuevos elementos modificados a la tabla
 For i As Integer = 0 To arrayCopia.Length - 1
 tablaPrueba.Add(arrayCopia(i).Key, "España")
 Next

Categorías
asp.net

Inyeccíon de dependencia en asp.net

En el ámbito del desarrollo de software, siempre es bueno eliminar dependencias. En otros términos, bajar el nivel de acoplamiento.

Hay casos en que se logra más directamente y otros en que no es tan simple.

Para estos últimos contamos con un pattern llamado Dependency Injection,Inyección de Dependencia, término por primera vez usado por Martin Fowler. Si te interesa ir a la fuente, acá está su documento sobre Dependency Injection.

En este post voy a intentar explicar que viene a resolver este patrón y sus distintas implementaciones.

Cuando tenemos un objeto que necesita de otro para funcionar correctamente, tenemos definida una dependencia. Esta dependecia puede ser altamente acopladatight coupling, o levemente acopladaloose coupling. Si el acoplamiento es bajo el objeto independiente es fácilmente reemplazable, si, en cambio el acoplamiento es alto, el reemplazo no es fácil y se dificulta el diseño de tests unitarios.

Supongamos que tenemos una clase que define un producto, que necesita un componente, este componente puede provenir de distintos fabricantes, en general cubren las mismas funciones. Los productos son varios y alternativamente pueden valerse del componente de cualquier fabricante.

Si instanciamos uno de los componentes en forma directa necesitamos referenciarlo. Si el mercado nos exige cambiar de componente, tendríamos que eliminar la referencia anterior, crear la nueva, revisar si los métodos, funciones y propiedades son homogéneos, si no lo son, corregir el código donde sea necesario… Si a esto le agregamos que valdría la pena tener una versión con el primer componente y otra con el segundo, la situación empeora. Si hubiera cincuenta componentes alternativos, la situación ya sería inmanejable.

Acá es donde la necesidad del patrón Dependency Injection se hace evidente.

Supongamos que este conjunto de componentes ejecuta básicamente cuatro métodos, que son los que nosotros necesitamos: Initialize, Shutdown, Prepare y DoIt.

Entonces comencemos por escribir una interface que defina estos cuatro métodos:

[VB]

Public Interface ISomeHardware
Sub Initialization()
Sub Shutdown()
Sub Prepare()
Sub DoIt()
End Interface

[C#]

public interface ISomeHardware
{
void Initialization();
void Shutdown();
void Prepare();
void DoIt();
}

Las clases que definan los componentes deben implementar la interfaceISomeHardware. En nuestro ejemplo, ComponentA y ComponentB:

[VB]

Public Class ComponentA
Implements ISomeHardware
Public Sub InitializationBegin() ImplementsISomeHardware.Initialization

End Sub
Public Sub ShutdownBegin() Implements ISomeHardware.Shutdown

End Sub
Public Sub PrepareBegin() Implements ISomeHardware.Prepare

End Sub
Public Sub DoItBegin() Implements ISomeHardware.DoIt

End Sub
End Class

Public Class ComponentB
Implements ISomeHardware

Public Sub InitializationBegin() ImplementsISomeHardware.Initialization

End Sub
Public Sub ShutdownBegin() Implements ISomeHardware.Shutdown

End Sub
Public Sub PrepareBegin() Implements ISomeHardware.Prepare

End Sub
Public Sub DoItBegin() Implements ISomeHardware.DoIt

End Sub
End Class

[C#]

class ComponentA : ISomeHardware
{
public void Initialization() { }
public void Shutdown() { }
public void Prepare() { }
public void DoIt() { }
}

class ComponentB : ISomeHardware
{
public void Initialization() { }
public void Shutdown() { }
public void Prepare() { }
public void DoIt() { }
}

Aclaración: Acá hago una simplificación a efecto didáctico. Las clases que definen ComponentA y ComponentB, en realidad debieran ser wrappers de las dll’s provistas por los fabricantes. Para no complicar inútilmente las dejaré así.

Veremos tres implementaciones del patrón Dependency Injectionpor Constructorpor Setter por Interface.

POR CONSTRUCTOR:

Ahora voy a usar otro patrón llamado Facade o Fachada, la idea es encapsular todos los aspectos complejos de un subsistema de clases en una única y simple interface. En nuestro caso, ProductFacade:

[VB]

Public Class ProductFacade
Private SomeHardware As ISomeHardware
Public Sub New(ByVal pSomeHardware As ISomeHardware)
SomeHardware = pSomeHardware
End Sub
End Class

[C#]

public class ProductFacade
{
private ISomeHardware SomeHardware;
public ProductFacade(ISomeHardware SomeHardware)
{
this.SomeHardware = SomeHardware;
}
}

En esta clase se implementa la Inyección de Dependencia por medio delconstructor, que acepta un parámetro de entrada de tipo de interfaceISomeHardware. Este punto es determinante. Cualquier clase que implemente la interface ISomeHardware es aceptada como parámetro del constructor de ProductFacade. Este es todo el secreto.

Entonces, para inyectar la dependencia de un componente de un fabricante u otro por Constructor, se hace así:

[VB]

Dim ComponentA As ISomeHardware = New ComponentA
Dim Product01 As ProductFacade = New ProductFacade(ComponentA)
 
Dim ComponentB As ISomeHardware = New ComponentB
Dim Product02 As ProductFacade = New ProductFacade(ComponentB)

[C#]

ISomeHardware componentA = new ComponentA();
ProductFacade product01 = new ProductFacade(componentA);
 
ISomeHardware componentB = new ComponentB();
ProductFacade product02 = new ProductFacade(componentB);

Realmente elegante.

Para las siguientes dos implementaciones del patrón, usaremos la misma interface ISomeHardware y la definición de las clases ComponentA yComponentB.

Las variaciones estarán en la Fachada y en la Inyección de Dependencia.

POR SETTER:

En este caso la Inyección de Dependencia se efectiviza a través de unapropiedad definida en la Fachada.

[VB]

Public Class ProductFacade
Private mSomeHardware As ISomeHardware
 
Public Property SomeHardware() As ISomeHardware
Get
Return mSomeHardware
End Get
Set(ByVal value As ISomeHardware)
mSomeHardware = value
End Set
End Property
End Class

[C#]

public class ProductFacade
{
private ISomeHardware SomeHardware;
public ISomeHardware Component
{
get
{
return SomeHardware;
}
set
{
SomeHardware = value;
}

}

}

Para el caso de Setter, la Inyección de Dependencia queda determinada así:

[VB]

Dim ComponentA As ISomeHardware = New ComponentA
Dim Product01 As ProductFacade = New ProductFacade()
Product01.SomeHardware = ComponentA

Dim ComponentB As ISomeHardware = New ComponentB
Dim Product02 As ProductFacade = New ProductFacade()
Product02.SomeHardware = ComponentB

[C#]

ISomeHardware componentA = new ComponentA();
ProductFacade product01 = new ProductFacade();
product01.Component = componentA;
ISomeHardware componentB = new ComponentB();
ProductFacade product02 = new ProductFacade();
product02.Component = componentB; 

POR INTERFACE:

Ahora la Inyección de Dependencia está implementada sobre un métodoque acepta un parámetro de tipo de interface ISomeHardware.

[VB]

Public Class ProductFacade
Private mSomeHardware As ISomeHardware
Public Sub SetComponent(ByVal pSomeHardware As ISomeHardware)
mSomeHardware = pSomeHardware
End Sub
End Class

[C#]

public class ProductFacade
{
private ISomeHardware SomeHardware;
public void SetComponent(ISomeHardware SomeHardware)
{
this.SomeHardware = SomeHardware;
}
}

Cuando la Inyección de Dependencia es por Interface, se invoca de esta forma:

[VB]

Dim ComponentA As ISomeHardware = New ComponentA
Dim Product01 As ProductFacade = New ProductFacade()
Product01.SetComponent(ComponentA)
 
Dim ComponentB As ISomeHardware = New ComponentB
Dim Product02 As ProductFacade = New ProductFacade()
Product02.SetComponent(ComponentB)

[C#]

ISomeHardware componentA = new ComponentA();
ProductFacade product01 = new ProductFacade();
product01.SetComponent(componentA);
 
ISomeHardware componentB = new ComponentB();
ProductFacade product02 = new ProductFacade();
product02.SetComponent(componentB);

Las tres implementaciones difieren sutilmente entre si. La diferencia más importante que yo encuentro es que, Por Constructor, nos obliga a inyectar al crear la clase, mientras que las otras modalidades, la difieren para más adelante.

La diferencia entre estas dos últimas está en si se prefiere inyectar la dependencia en el set de una propiedad, Por Setter, o como argumento de un parámetro de entrada a un método o función, Por Interface. Cuestión de gusto sintáctico.