Mostrando las entradas con la etiqueta C#. Mostrar todas las entradas
Mostrando las entradas con la etiqueta C#. Mostrar todas las entradas

miércoles, septiembre 22, 2010

Calcular fechas laborables con Ruby

Hoy me encontré con este post llamado "Calculate Business Days using LINQ" donde explican como usar C# y LINQ para de un rango de fechas obtener solo las fechas que son laborables, es decir excluir las fechas que caigan en sábado y domingo.

El código se muestra a continuación donde se haca primero una llamada al método GetAllDates y se le pasa una fecha inicial y otra final, después con Where de LINQ se evalúa cada fecha un método que regresa falso o verdadero si la fecha cae en fin de semana o no, obteniendo al fina un arreglo con las fechas laborables.


Después de revisarlo, me pregunte, que tan complicado es hacer lo mismo en Ruby. Después de unos minutos me di cuenta que es ridículamente simple hacer lo mismo que LINQ y C# en solo 1 linea de código.

A mi metodo wroking_days se le pasa una fecha inicial y una fecha final y como resultado tenemos una arreglo de fechas excluyendo las que caen en fin de semana.




miércoles, noviembre 26, 2008

LINQ2SQL: Recuperandonos de errores al crear un registro nuevo

El día de hoy me preguntaron como manejar conflictos en el DataContext de LINQ al insertar nuevos datos - específicamente si falla debido a un valor duplicado en algún cambio que tenga indice único -.

Supongamos que tenemos el siguiente método que nos permite crear una nueva Categoría en nuestra DB, tomando como entrada la categoría y la descripción de la misma; categoría en nuestra base de datos tiene un indice de tipo único, por lo tanto no pueden existir dos categorías con el mismo nombre.

private void CreaCategoria(string categoria, string descripcion)
{
var categoria = new Categoria(categoria, descripcion);
context.Categoria.InsertOnSubmit(categoria); // context es un DataContext inicializado en alguna
          // parte de nuestro programa y Categoria es el 
          // nombre de nuestra tabla

try
{
context.SubmitChanges(ConflictMode.FailOnFirstConflict);
} catch (ChangeConflictException ex)
{
// Manejo de la excepcion, a la mejor un MessageBox al usuario indicando el error.
}
} 

El método aquí mostrado va funcionar correctamente en nuestro escenario si lo llamamos para crear una categoría nueva:

CreaCategoria("Categoria 1", "Primera categoria");

Pero si lo mandamos llamar para crear otra categoria con el mismo nombre el método va a fallar y vamos a recibir el mensaje de alguna forma.

CreaCategoria("Categoria 1", "Segunda categoria");

Falla, porque como se menciono el campo Categoria tiene un indice único, y aunque llamemos una tercera vez el método con los valores correctos:

CreaCategoria("Categoria 2", "Segunda categoria");

El método va continuar fallando aun y cuando ya estamos creando un nuevo objeto con los valores correctos, esto se debe a que el DataContext que creamos mantiene registro del registro invalido de nuestro intento previo al anterior.

La forma de como solucionar esto es, agregando lógica en el bloque de captura de la excepción para que que el DataContext elimine ese dato invalido de su registro, esto lo podemos hacer manipulando la colección ChangeConflicts que nos ofrece DataContext y que es donde residen todos los objetos con algún problema.

Podemos recuperarnos de este error de dos forma, la primera es eliminando todos los objetos con conflicto en nuestro DataContext, lo cual no puede ser muy buena idea, pero si así lo deseamos, lo podemos hacer de la siguiente forma:

context.ChangeConflicts.Clear();

o podemos ser mas especifico y solo eliminar el objeto que estamos tratando de insertar:

context.ChangeConflicts.Remove(categoria);

Por lo tanto nuestro método quedaría como sigue, y nos permitiría intentar crear una vez mas la categoría, ya que el usuario soluciono el problema:

private void CreaCategoria(string categoria, string descripcion)
{
var categoria = new Categoria(categoria, descripcion);
context.Categoria.InsertOnSubmit(categoria); // context es un DataContext inicializado en alguna
          // parte de nuestro programa y Categoria es el 
          // nombre de nuestra tabla

try
{
context.SubmitChanges(ConflictMode.FailOnFirstConflict);
} catch (ChangeConflictException ex)
{
// Manejo de la excepcion, a la mejor un MessageBox al usuario indicando el error.
context.ChangeConflicts.Remove(categoria);
}
} 

jueves, septiembre 18, 2008

Programación Web: Patrón MVC

Los patrones son una parte importante en el desarrollo de aplicaciones, ya que nos proporcionan soluciones probadas para problemas comunes o recurrentes.

En este caso el patrón MVC ofrece una metodología consistente en el desarrollo de aplicaciones que interactuan con el usuario para la manipulación de información.

MVC es un patrón de arquitectura y que debe su nombre a los tres elementos que lo componen, Model-View-Controller (Modelo-Vista-Controlador). El objetivo de este patrón es separar la lógica de negocios de la interface gráfica de manera que cambios en la misma no afecten a la lógica de negocios. A este concepto de aislar bloques de nuestra aplicación de otros mas que la componen se le conoce como "Separación de preocupaciones" (Separation of concerns - SoC -)

El modelo representa a la información que tanto el usuario como la aplicación puede manipular. La vista implica todos los elementos que componen la interface gráfica, como cuadros de texto, botones, rejillas, etc.

El controlador maneja la interacción y la comunicación entre el modelo y las acciones del usuario como teclas o movimientos del mouse.

Este patrón fue descrito en 1979 por Trygve Reenskaug y fue implementado inicialmente en el lenguaje Smalltalk. Durante este tiempo, este patron ha sido implementado en una gran cantidad de Frameworks para aplicaciones Web y de escritorio como:
Aunque últimamente ha cobrado popularidad en el desarrollo de aplicaciones Web, su uso en aplicaciones de escritorio es extendido, por ejemplo Oracle Applications, que es el software ERP de Oracle, ha migrado algunos de sus módulos de Oracle Forms al framework Oracle Applications Framework.

Otro caso es OSX cuyo modelo de programación para aplicaciones con el framework Cocoa es basado en el patrón MVC, por lo tanto, prácticamente todas las aplicaciones que se ejecutan en OSX funcionan con este patrón.

Después de esta introducción nos vamos a enfocar en como el framework ASP.NET MVC funciona y de que manera lo podemos utilizar en conjunto con el patrón ActiveRecord implementado por Castle ActiveRecord.

El Microsoft ASP.NET MVC framework es relativamente nuevo, a finales del 2007 se anuncio sobre el inicio de sus desarrollo, durante este tiempo Microsoft ha hecho publico su código fuente (bajo una licencia muy limitada), ademas de publicar cinco "Code Previews" y con la promesa de tener una versión beta disponible en los próximos meses.

La forma en como este patrón funciona en ASP.NET MVC se describe a continuación
  1. El usuario navega hacia una URL de nuestro sitio web
  2. El controlador correcto recibe la acción que se debe ejecutar
  3. El controlador se comunica para modelo para indicar alguna acción a tomar
  4. El modelo regresa datos si es que la acción que se esta ejecutando así lo requiere
  5. El controlador pasa los datos a la vista a través del objeto ViewData, y llama a la vista
  6. La vista, que funciona como plantilla, genera el código HTML que se desplegara en el navegador del usuario al final de la acción.

ASP.NET MVC Framework
La introducción presentada aquí al ASP.NET MVC Framework es una introducción rápida, donde se omiten algunos detalles conscientemente con la finalidad de que el post no sea muy largo, ademas de que el tema aquí tratado se vio en el curso que se llevo a cabo en el ITT.

Cuando creamos un nuevo proyecto para MVC desde Visual Studio, por omisión se crea la siguiente estructura de de directorios, que si bien no es necesario usarla estrictamente, si es recomendable utilizarla:

/Controllers
/Models
/Views

En el directorio Controllers es donde debemos colocar nuestras clases que funcionan como controladores, Models es donde deben de ir nuestras clases que representan datos y finalmente Views es donde colocamos nuestras plantillas ASP.NET que se van a encargar de generar nuestra interface HTML.

El Controlador

En ASP.NET MVC existe una convención por omisión acerca de como vamos a nombrar las clases que corresponden a nuestros controladores, esta convención nos indica que por ejemplo para nuestro controlador de restaurantes, el nombre debe de ser RestauranteController, ademas debe de derivarse de la base base System.Web.MVC.Controller.

Por lo tanto cuando naveguemos hacia el URL /Restaurante/, este será manejado por el controlador restaurante. Cada controlador responde a un grupo de acciones definidas para él, mediante métodos públicos, por lo tanto si deseamos que nuestro controlador realice una acción nuestra URL debe de ser /Restaurante/Menu, en donde menu es la acción a ejecutar.

Nuestras acciones pueden recibir parámetros, cuyos valores pueden provenir, por ejemplo de una forma HTML, si nuestro método solo recibe un parámetro, por ejemplo de tipo entero, la URL para nuestra acción se vería así: /Restaurante/Menu/1, donde 1 es el parámetro entero que acepta nuestra acción; si la acción acepta mas de un parámetro, la forma en como estos se representaran en nuestra URL es de la siguiente forma: /Restaurante/Menu/1?parametro2=34; donde parametro2 es el nombre de nuestro segundo parámetro cuyo valor es 34.


public class RestauranteController : Controller
{
public ActionResult Index()
{
return View();
}

public ActionResult Menu(int restaurante)
{
return View();
}
}
Algo importante a notar en la definición de nuestras acciones realmente son funciones que regresan el tipo ActionResult, este es un tipo especial que en nuestro caso cuando se ejecuta la instrucción return View(), sucede que la vista es cargada y ejecutada para producir el código HTML que va a ser presentado en el navegador Web.

El ruteo

Como se vio el ASP.NET MVC hace uso de ciertas convenciones para realizar su trabajo, una de estas convecciones esta relacionada en como la URL es interpretada para luego ser enviada al controlador/accion correcta.

El manejo de la URL proviene de una tabla de rutas con las cuales se define como la URL va a trabajar en nuestra aplicación, la convención por omisión estable que la URL va a ser interpretada como: [controlador]/[accion]/[parametro], pero no es posible cambiarla de manera que se ajuste mejor a nuestras necesidades.

La configuración de ruteo se encuentra en el archivo Global.asax de nuestro proyecto, ahí vamos a encontrar el método RegisterRoutes, el cual tiene definida la manera por omisión en como nuestra aplicación va a interpretar las URL que el usuario navegue.


public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

}
Esta ruta especifica lo que hemos venido observando en nuestra aplicación, que la primera parte de nuestra URL corresponde al controlador, la segunda parte indica la acción a ejecutar y la tercera parte pertenece a los parámetros.

También especifica que si recibimos una URL sin parámetros, nuestro parámetro va a ser nulo, si la URL no cuenta con la acción a ejecutar, entonces se llamara la acción Index de nuestro controlador, por lo tanto es importante tener una acción Index; finalmente también indica que si no especificamos el controlador, entonces la petición se dirigirá al controlador Home con la acción Index.

En esta sección de nuestro programa podemos agregar nuevas rutas con diferentes características que satisfagan nuestras necesidades, solo hay que tener en cuenta que las rutas son evaluadas en el orden que se registran.

Vistas

Las vistas en nuestra aplicación de MVC se encuentran en el directorio /Views, dentro de este directorio existe una sub-estructura de directorios, que una vez mas, obedecen a una convención de nombres sobre la cual funciona el framework.

Dentro del directorio /Views encontramos un directorio Shared, el cual contiene un archivo de Master Pages, Site.master, este archivo es la plantilla HTML que nuestra aplicación va a utilizar, la naturaleza de este archivo es proveer de una interface unificada en toda la aplicación. Esta plantilla global cuenta con una sección la cual funciona como un contenedor, el cual va a ser llenado con el HTML generado por nuestras vistas.

Este archivo Site.master debe de contener un tag:


<asp:ContentPlaceHolder ID="MainContent" runat="server" />
Con el cual indicamos que en esa sección es donde deseamos que el contenido generado por nuestra vista se despliegue, así que si creamos una plantilla maestra, hay que recordar agregar ese tag.

Volviendo al contenido de nuestro directorio /View, también encontramos un folder por cada uno de los controladores de nuestra aplicación, y cada uno de estos folders tienen por nombre el mismo nombre del controlador al que pertenecen.

Dentro de cada folder con nombre de controlador vamos a encontrar archivos cuyo nombre corresponden a las acciones de nuestro controlador, los archivos tienen la extensión .aspx, lo cual nos indica que que son archivos de ASP.NET, pero estos archivos en realidad son plantillas MVC.

La gran diferencia es que las vistas MVC en ASP.NET MVC no contienen controles ASP.NET, sino controles HTML, aunque dentro de las plantillas colocamos código en C# o VB.NET dentro de los tags <% %>, este código corresponde a lo que se conoce como "Ayudantes de HTML" (HTML Helpers), los cuales son implementados como métodos de extensión (Extension Methods) y cuya finalidad es que al momento que nuestra vista es evaluada para enviar el código HTML a cliente, los ayudantes de html generen el código HTML apropiado.

Loas ayudantes de HTML predefinidos nos permiten crear una gran variedad de objetos HTML, por ejemplo si deseamos agregar una liga dentro de nuestra vista, el código del ayudante que realizaría esta acción es:

<%= Html.ActionLink("Comprar", "Comprar", new {id = 1}) %>
Este código va a generar la siguiente liga en HTML:


<a href="/Restaurante/Comprar/1">Comprar</a>
El primer parámetro de Html.ActionLink es el texto que se va a desplegar con la liga, el segundo es la acción del controlador a la cual la liga nos va a enviar y finalmente pasamos un parámetro para nuestra acción, en este caso el valor entero 1.

Existe un mecanismo mediante el cual podemos enviar desde el controlador la información gestionada con el modelo a la vista, para tal efecto tenemos un objeto de tipo Dictionary < string, object > llamado ViewData al cual podemos hacer referencia desde el controlador y desde la vista.

Por ejemplo si deseamos enviar información a nuestra vista, podemos usar el objeto ViewData de la siguiente forma:


ViewData["MiLlave"] = "Mensaje a desplegar en la vista";
"MiLlave" representa el identificador dentro del objeto diccionario con el cual vamos a poder acceder al dato guardado, por ejemplo si queremos imprimir ese mensaje en nuestra vista, lo podemos hacer de la siguiente manera:

<% Html.Encode(ViewData["MiLlave"]) %>
El objeto ViewData tiene una propiedad que es especifica para pasar la información de nuestro modelo a la vista, esta propiedad es Model, por ejemplo para pasar el objeto mimodelo a la vista lo hacemos así:
ViewData.Model = mimodelo;

Para acceder al modelo desde la vista lo hacemos de la siguiente forma:

<% Html.Encode(ViewData.Model.Dato) %>
Aquí asumimos que el objeto mimodelo tiene una propiedad llamada Dato, que es la que nuestra vista despliega.

Modelo

El modelo en una aplicación representa a los datos con los cuales la aplicación va trabajar. El modelo se compone de un grupo de clases que sirven para representar un dominio de información, la información puede provenir de diferentes fuentes como base de datos relacionales, archivos de texto, servicios REST.

De igual forma el modelo puede administrado por diferentes tecnologías, técnicas o patrones, tal y como se describió en el post "ActiveRecord".

Para el caso de la aplicación que se vio durante este curso, nuestro modelo esta implementado con el patrón ActiveRecord y específicamente con las librerías Castle ActiveRecord.

Par tal motivo esta sección se va a destinar a indicar como habilitar Castle ActiveRecord para que funcione con el ASP.NET MVC.

El primer paso va a ser agregar las referencias necesarias a nuestro proyecto MVC. Primeramente necesitamos referencias las librerías NHibernate.dll y Castle.ActiveRecord.dll, posteriormente agregamos la referencia a nuestra librería que contiene nuestros modelos de ActiveRecord, esta librería es ITT.ParaLlevar.Model.

Nuestro siguiente paso es agregar al archivo Web.config la configuración de ActiveRecord, dentro de la sección < configSection/ > agregamos la siguiente configuración:

<section name="activeRecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler,
Castle.ActiveRecord"
/>

Dentro del mismo Web.config dentro de la sección < configuration/ > agregamos las siguientes lineas que configuran ActiveRecord con nuestra base de datos relacionales, hay que recordar modificar la cadena de conexión para que refleje el nombre de nuestro servidor:

<activeRecord isWeb="true">
<config>
<add key="hibernate.connection.driver class"
value="NHibernate.Driver.SqlClientDriver"/>
<add key="hibernate.dialect"
value="NHibernate.Dialect.MsSql2000Dialect"/>
<add key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="hibernate.connection.connection_string"
value="Data Source=SERVIDOR;Initial Catalog=ParaLlevar;Integrated Security=True"/>
</config>
</activeRecord>

Esta configuración es exactamente la misma que la configuración que teníamos en nuestro archivo AR.cfg.xml de la aplicación de Windows.Forms, el único cambio es que en el tag < activeRecord > agregamos la propiedad isWeb="true".

Ahora debemos inicializar ActiveRecord dentro de nuestra aplicación, por lo tanto nos vamos a dirigir al archivo Global.asax, ahí buscamos el metodo Application_Start() y agregamos las siguientes lineas:

var source = System.Configuration.ConfigurationManager.GetSection("activeRecord") as Castle.ActiveRecord.Framework.IConfigurationSource;

Castle.ActiveRecord.ActiveRecordStarter.Initialize(typeof(Restaurante).Assembly, source);

Y con esto estamos listos, podemos regresar y completar nuestro controlador Restaurante para que gestione información del modelo y la pase a la vista, nuestro controlador completo quedaría como sigue:

public class RestauranteController : Controller
{

public ActionResult Index()
{
var restaurantes = Restaurante.FindAll();

ViewData.Model = restaurantes;
return View();
}

public ActionResult Menu(int id)
{
var restaurante = Restaurante.GetById(id);
ViewData.Model = new RestauranteData {Restaurante = restaurante};

return View();
}

public ActionResult Comprar(int id)
{
return View();
}
}

Ahí podemos ver claramente como nuestro controlador gestiona la información, la pasa a través del objeto ViewData y su propiedad Model, para finalmente con return View() llama la vista apropiada para su evaluación. Nuestra vista para la acción Index() se vería así:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ITT.ParaLlevar.Web.Views.Restaurante.Index" %>
<%@ Import Namespace="ITT.ParaLlevar.Model"%>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<ul>
<% foreach (var restaurante in (ViewData.Model as Restaurante[])) { %>
<li>
<%= Html.ActionLink(restaurante.Nombre, "Menu", new { id = restaurante.Id })%>
</li>
<%} %>
</ul>
</asp:Content>

Lo que nos da como resultado una lista con los restaurantes registrados en nuestra base de datos.

Conclusión
Como mencione casi al principio de este post, tanto este como el post de ActiveRecord hablan sobre patrones establecidos en la industria para resolver problemas recurrentes, ambos post son parte del curso donde se discutió con un poco mas de detalle cada uno de los temas.

En ambos posts se omitieron algunos detalles de la implementación debido al tiempo y a la longitud de las mismo. El código fuente que acompaña ambos posts, no representa una aplicación completa, mas bien ilustra los puntos a resaltar.

Aunque los post estuvieron centrados sobre Castle ActiveRecord y ASP.NET MVC, el conocimiento de ambos patrones es ampliamente utilizados en diferentes lenguajes/tecnologias, por lo tanto el conocimiento no se limita a estos dos frameworks.

Referencias

jueves, septiembre 11, 2008

Codigo de ejemplo del patrón ActiveRecord

Aquí esta el archivo zip con los cambios realizados el día de ayer al ejemplo de ActiveRecord.

NOTA: No olviden modificar el archivo AR.cfg.xml para indicar el nombre de su servidor de SQL, en caso contrario el programa va a fallar.

Para los ejercicios del día de hoy, hay que descargar e instalar la librería ASP.NET MVC. Bajar el archivo "ASP.NET MVC Codeplex Preview 5"

miércoles, septiembre 10, 2008

Accesos a base de datos: Patrón ActiveRecord

Uno de los problemas con los que nos enfrentamos cuando trabajamos con aplicaciones que hace uso de datos, por ejemplo almacenados en una base de datos relacional, es que estrategia elegir para acceder a ellos y poder consumirlos en nuestra aplicación orientada a objetos.

Este no es un problema trivial, debido a que tratamos de integrar dos paradigmas que manipulan la información de maneras muy diferentes, por un lado tenemos el paradigma relacional, con el cual podemos relacionar nuestros datos mediante uniones de nuestras tablas, y por otro lado tenemos el paradigma orientado a objetos que mediante relaciones entre los objetos podemos "navegar" a través de los datos.

Otros problemas son por ejemplo los diferentes tipos de datos que se manejan en una base de datos relacional y los que se manejan en nuestro lenguaje orientado a objetos; otro problema puede ser la estructura que almacena los datos en la base de datos relacional, puede ser muy diferente a nuestro modelo de objetos en nuestra aplicación orientada a objetos.

A todos estos problemas se le conoce como Impedancia de Discordancia Objeto-Relacional. Existen varias técnicas y patrones para tratar de minimizar los problemas que esta incompatibilidad entre los dos paradigmas crea. Todas las soluciones se centran principalmente en realizar un "mapeo" entre nuestros datos relaciones y nuestros objetos, a esta técnica se le conoce como ORM (Object-Relational Mapping)

En .NET tenemos varias opciones para acceder desde un modelo de objetos a un modelo relacional:

ADO.NET: Son las librerías base que permiten la conexión a datos, esta es la forma mas básica y a mas bajo nivel de como acceder a datos, requiere de una buena cantidad de esfuerzo para hacerla funcionar con nuestra aplicación.

Generadores de código DAL: Existen otras soluciones que generan código fuente a partir de un esquema de base de datos, el código generado generalmente conforma lo que se conoce como un Data Access Layer, la cual representa una capa en nuestra aplicación que contiene todo el comportamiento y lógica para acceder a nuestros datos a partir de nuestros objetos. Como ejemplo de estos generadores esta SubSonic.

ORM: Son librerías que integramos en nuestra aplicación a la cual le alimentamos una descripción de como nuestros objetos "mapean" a nuestros datos relacionales, y la librería ORM se encarga de gestionar la interacción con la base de datos y nuestros objetos de forma transparente para nosotros. Una forma común de indicar como nuestros objetos mapean a nuestra base de datos es mediante archivos XML. Ejemplo de este tipo de librerías es NHibernate y MS LINQ

Para el acceso a datos de nuestra aplicación vamos a hacer uso de librerías ORM. La librería que vamos utilizar hace uso de un patrón llamado ActiveRecord, de ahí el nombre de la librería es Castle ActiveRecord.

ActiveRecord es un patrón en el cual, el objeto contiene los datos que representan a un renglón (o registro) de nuestra tabla o vista, ademas de encapsular la lógica necesaria para acceder a la base de datos. De esta forma el acceso a datos se presenta de manera uniforma a través de la aplicación.



El patrón de ActiveRecord es utilizado en diferentes lenguajes/tecnologias como una manera estándar de acceder a datos, por ejemplo lo podemos encontrar en Ruby on Rails, CakePHP y por supuesto .NET a través de Castle ActiveRecord.

Castle ActiveRecord es una capa implementada encima de la librería ORM NHibernate, NHibernate hace uso de archivos XML para mapear objetos a datos relacionales, lo cual requiere de una curva de aprendizaje relativamente grande; ActiveRecord ayuda a minimizar esta curva, ya que a través de programación declarativa auto-genera los archivos de mapeo XML por nosotros.

Por ejemplo si tenemos la siguiente tabla en nuestra base de datos y deseamos leer un registro en nuestro objeto, la clase tendría que ser declarada de la siguiente forma:


[ActiveRecord]
public class Restaurante : ActiveRecordBase<restaurante>
{
[PrimaryKey(PrimaryKeyType.Native)]
public int Id { get; set; }

[Property]
public string Nombre { get; set; }

[Property]
public string Direccion { get; set; }

[Property]
public string Zona { get; set; }

[Property]
public string Telefono { get; set; }
}
</restaurante>

Los elementos entre [ ] se llaman atributos y es una forma declarativa de indicarle a ActiveRecord que propiedades de nuestra clase van a mapearse a un campo de la tabla. Si el nombre de la propiedad no corresponde con el nombre del campo entonces el atributo property lo podemos declarar como:

[Property("CampoTabla")]
, donde "CampoTabla" corresponde al campo de nuestra tabla.

Otro punto importante a notar aquí es que la clase esta marcada con el atributo [ActiveRecord], con el cual indicamos que nuestra clase va aser manejada por ActiveRecord, al igual que el atributo Property, si el nombre de nuestra clase no corresponde al nombre de la tabla, podemos colocar el atributo de la siguiente forma:

[ActiveRecord("MiTabla")]

Ademas de los atributos, es necesario que nuestra clase herede de la clase ActiveRecordBase, ya que esta clase base nos va a proporcionar el comportamiento necesario para poder realizar operaciones CRUD (Create, Read, Update and Delete; Crear, Leer, Actualizar y Borrar), a través de una serie de métodos estáticos.

Con los métodos estáticos Find* podemos realizar cualquier consulta sobre nuestros registros, por mas compleja que esta sea, pero como buenos desarrolladores que somos vamos agregar una serie de métodos estáticos adicionales sobre consultas que pueden resultar comunes, para quien consuma nuestras clases le sea mas fácil utilizarlas. Por ejemplo una par de consultas comunes pueden ser el buscar un restaurante por su llave primaria o bien por el nombre del restaurante. A continuación se muestran ambas consultas como serian usando únicamente los métodos Find*:

// Busqueda por llave primary, para restaurante con llave 1
Restaurante restaurante = Restaurante.FindByPrimaryKey(1);

// Busqueda por nombre, esta consulta también puede ser escrita con los métodos FindOne o FindFirst
Restaurante[] restaurantes = Restaurante.FindAllByProperty("Nombre", "Nombre del restaurante a buscar");
Restaurante restaurante;
restaurantes.Length > 0 ? restaurante = restaurantes[0] : restaurante = null;

Para ambas consultas podemos agregar los siguientes métodos estáticos a nuestra clase Restaurante:

public static Restaurante GetById(int id)
{
return Restaurante.FindByPrimaryKey(id);
}

public static Restaurante GetByName(string restaurante)
{
var restaurantes = Restaurante.FindAllByProperty("Nombre", restaurante);

return restaurantes.Length > 0 ? restaurantes[0] : null;
}

De forma que los usuarios de nuestra clase solo tengan que escribir:

Restaurante restaurante = Restaurante. GetById(1);

ó

Restaurante restaurante = Restaurante. GetByName("Nombre del restaurante a buscar");

ActiveRecord nos ofrece una serie de métodos para persistir cambios a la base de datos como Create, Delete, Save y Update, todos ellos mantienen nuestros cambios en memoria en un objeto llamado Session, en el momento que la sesión recibe un llamado a un método que en nombre tenga la palabra Flush, los cambios son enviados a la base de datos. SI queremos que nuestros cambios se vayan inmediatamente entonces podemos llamar los métodos CreateAndFlush, DeleteAndFlush, SaveAndFlush y finalmente UpdateAndFlush.

Una de las complicaciones de los datos relacionales al querer manipularlos como objetos, son las relaciones, por ejemplo podemos tener dos o mas tablas que están relacionadas entre si, por medio una llave externa o "Foreign Key", las cuales podemos relacionar mediante un "join", en el caso de los objetos cuando tenemos una relación de, por ejemplo encabezado/detalle.
En nuestros objetos debemos tener una propiedad, en la clase que sirva como encabezado, la cual sea una colección de los objetos que representan el detalle , por ejemplo en el caso de nuestra clase Restaurante, es importante poder acceder a el listado de menús para cada restaurante:

IList<Menu> menus = Restaurante.Menus;

La forma en como podemos representar estas relaciones en ActiveRecord es también a través de programación declarativa, en donde tenemos los atributos HasMany, BelongsTo, OneToOne, HasAndBelong y HasManyToAny, por ejemplo en nuestro caso donde un restaurante puede tener una o mas opciones de menu la vamos a representar con los atributos HasMany y BelongsTo.

Primeramente en nuestra clase Restaurante vamos a agregar una nueva propiedad llamada Menus la cual va a contener una colección de los menús que ese restaurante ofrece:

[HasMany(typeof(Menu), Inverse = true, Cascade = ManyRelationCascadeEnum.All)]
public IList&lt;menu&gt; Menus { get; set; }

Donde a HasMany le indicamos que la relación va a ser con nuestra clase Menu, en nuestra clase Menu también agregamos una nueva propiedad y la marcamos con el atributo BelongsTo donde le indicamos cual es el campo en nuestra tabla Menu que nos va a dar la relación con la tabla Restaurante.

[BelongsTo("RestauranteId")]
internal Restaurante Restaurante { get; set; }

De forma que podemos recorrer nuestra colección de Menu a través de un objeto Restaurante.

Para finalizar es necesario configurar e iniciailizar ActiveRecord en nuestra aplicación. La configuración nos permite indicar a que tipo de base de datos relacional nos vamos a conectar ademas de indicar la cadena de conexión que contenga la información del servidor, base de datos e información de seguridad, esta configuración se realiza por medio de un archivo XML. Un ejemplo de este archivo es el siguiente:

<activerecord>
<config>
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
<add key="hibernate.connection.connection_string" value="Data Source=SERVIDOR;Initial Catalog=BASEDEDATOS;Integrated Security=True"/>
<add key="hibernate.show_sql" value="true"/>
</config></activerecord>

Es importante indicar el nombre de servidor de base de datos correcto, el nombre de la base de datos adecuado y la información de seguridad - usuario y clave si nuestro servidor lo requiere -.

Como ultimo paso es necesario inicializar ActiveRecord en nuestra aplicación, esta inicialización se debe de hacer únicamente una vez durante la ejecución de nuestra aplicación y antes de intentar utilizar alguna de las clases que creamos para usar con ActiveRecord:

var configurationSource = new XmlConfigurationSource("AR.cfg.xml");
ActiveRecordStarter.Initialize(typeof(Restaurante).Assembly, configurationSource);

AR.cfg.xml representa el archivo XML con la configuración para ActiveRecord.

Como conclusión, ActiveRecord es un patrón muy fácil de entender y utilizar en nuestras aplicaciones que requieren de acceso a base de datos, tal es la razón de que es un patrón popular en varios lenguajes.

Referencias e información
La siguiente lista de ligas contiene información mas extensa y detallada sobre ActiveRecord:

miércoles, febrero 06, 2008

Monodevelop en OSX

Ya en post anteriores había comentado que el equipo de Mono esta trabajando para mejorar el soporte de MWF y GTK# en OSX.

Uno de los objetivos es que ambos Frameworks trabajaran correctamente en OSX, el otro de los objetivos es que las aplicaciones se integraran con el sistema operativo, es decir que no se vieran "extrañas".

El trabajo aun esta en proceso, de hecho el día de ayer se libero una versión de pruebas para OSX.

Las mejoras visibles, sin entrar mucho en detalle son:
- Las aplicaciones MWF no "parpadean" cada vez que obtienen el "focus" o el "focus" es transferido a alguno de los controles de la forma
- Por primera vez se incluyó el ambiente de desarrollo Monodevelop 0.18, el cual corre - dentro de lo poco que lo probado - muy bien.
- Se incluye el programa MOMA que analiza aplicaciones MWF para determinar que clases de las que usa el programa aun no han sido implementadas, ademas de generar el reporte correspondiente.

martes, diciembre 18, 2007

Video Cast 3, Introducción a nueva funcionalidad en .NET 3.5

Por cuestiones de diversos pendientes, no me había sido posible realizar este Video Cast, pero finalmente aquí está. Este es el ultimo video cast de este año, pero a principios del 2008 estare presentado nuevos.

Ya esta disponible el tercer Video cast que muestra la nueva funcionalidad introducida en .NET 3.5, específicamente se muestra como funciona:
- Expresiones Lambda
- Introducción a LINQ

Las herramientas y librerías necesarias u opcionales se listan en este post.

El código fuente de ejemplo puede ser descargado de aquí. El archivo para este video cast es V3.zip

La liga directa al video esta aquí.



Creative Commons License
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Mexico License.

martes, diciembre 04, 2007

Video Cast 1, re-publicado

Por los motivos que comentó en este post, el Video Cast 1 ha sido re-publicado con una mejor calidad en la imágen, para mas detalles sobre este video cast, por favor consultar este post.

Liga directa al video esta aquí.




Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Mexico License.

Video Cast 2, Introducción a nueva funcionalidad en .NET 3.5

Ya esta disponible el segundo Video cast que muestra la nueva funcionalidad introducida en .NET 3.5, específicamente se muestra como funciona:
- Métodos de extensión (Extension methods)
- Tipos implícitos
- Tipos anónimos

Las herramientas y librerías necesarias u opcionales se listan en este post.

El código fuente de ejemplo puede ser descargado de aquí. El archivo para este video cast es V2.zip

La liga directa al video esta aquí.





Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Mexico License.

viernes, noviembre 30, 2007

Video Cast 2

Por problemas al subir el video al sitio de video.google.com, aun no he podido publicar el segundo video cast, aun y cuando esta listo desde principios de esta semana, espero tener un poco de mejor suerte el dia de hoy y quede el video.

miércoles, noviembre 21, 2007

Video Cast 1, Introducción a nueva funcionalidad en .NET 3.5

El primer Video cast esta enfocado a la nueva funcionalidad introducida en .NET 3.5, específicamente se muestra como funciona:
- El acceso automático a propiedades
- La nueva inicialización de objetos

Las herramientas y librerías necesarias u opcionales se listan en este post.

El código fuente de ejemplo puede ser descargado de aquí. El archivo para este video cast es V1.zip
La liga directa al video esta aquí.


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Mexico License.

martes, agosto 07, 2007

C# codigo intermedio, Vala C puro

Hace unos dias en el mundo Gnome encontre un proyecto interesante, el cual parace que esta ganando "momento", aun y cuando el proyecto se inicio alla por el 2006, este proyecto se llama Vala.

Como se describe en su pagina, Vala es un lenguaje moderno para el desarrollo de aplicaciones para el ambiente Gnome, el cual compila el codigo a C, permitiendo el uso directo de las librerias de Gnome escritas en C, sin la necesidad de una maquina virtual para la ejecucion del codigo - tal y como lo hace C# o Python -.

Vala esta basada en el sistema de tipos GObject, pero la pregunta es ¿porque Vala es un lenguage moderno de programacion?, bueno porque su sintaxis esta basada, nada menos que en C#!

Asi es Vala soporta caracteristicas existentes en C# 2.0 como pueden ser:
  • Interfaces
  • Ciclos foreach
  • Señales o eventos
  • Generics
  • Propiedades
  • Tipos no nulos
  • Manejo automatico de memoria, bueno usa "Reference counting"
  • Soporta manejo de excepciones con los bloques Try-Catch
Pero ademas implementa caracteristicas de C# 3.0 como son:
  • Expresiones Lambda
  • Inferecia de tipos (variables de tipo var)
El rasonamiento de Vala es que en Gnome existen programadores que no quieren/pueden usar lenguajes como C# o Java y estan "condenados" a utilizar C y la complejidad de programar para GObject, ahora van a poder usar un lenguaje que se encargue de la "plomeria" para seguir creando aplicaciones en un lenguaje moderno y sin tener que depender de una maquina virtual.

Para poder utilizar las librerias nativas de Gnome en Vala, es necesario crear "bindings" que son una capa que permite la comunicacion entre las librerias y el lenguage Vala, actualmente hay "hackers" que estan enfocados en esta tarea y se espera que un futuro proximo al menos las librerias basicas de Gnome cuenten con bindings para poder ser utilizadas con Vala.

Aqui muestro un par de ejemplos, el primero es interesante porque muestra el uso de: Propiedades, Eventos, Expresiones Lambda y ciclo foreach

// Para compilar, teclear: valac -o sample1 sample1.vala

using GLib;

public class Sample1
{
private string name {get; set;}
public Sample1 (construct string! name){}

public signal void Display();

public void run()
{
Display += s => {
stdout.printf ("Expresion Lambda %s!\n", name);
};

Display();
}

static int main(string[] args)
{
foreach(string arg in args)
{
var sample = new Sample1(arg);
sample.run();
}
}
}
El segundo ejemplo muestra como crear una aplicacion grafica con el toolkit Gtk+

//valac --pkg gtk+-2.0 -o sample sample.vala

using GLib;
using Gtk;

public class Sample : Window {
construct {
title = "Sample Window";
create_widgets ();
}

public void create_widgets () {
destroy += Gtk.main_quit;

var button = new Button.with_label ("Hello World");
button.clicked += btn => {
title = btn.label;
};

add (button);
}

static int main (string[] args) {
Gtk.init (out args);

var sample = new Sample ();
sample.show_all ();

Gtk.main ();
return 0;
}
}
El listado de la sintaxis de Vala se encuetra aqui.

Me llama la atencion que hallan decido implementar Vala con una sintaxis mas parecida a C# en lugar de Java, y me llama la atencion porque generalmente en el mundo OSS cualquer cosa que venga de Microsoft es maligna, en fin veremos que futuro le depara a Vala en el mundo Gnome.

Por cierto no existen paquetes de instalacion, asi que aqui estan las instrucciones de como compilarlo, ya que Vala se autocompila, pero lo tant es necesario contar con un compilador Vala para poder compilarse a si mismo, ok, ok se escucha complejo, pero es muy simple.

Primero hay que descargar algunos de los archivos tar liberados - el mas reciente es el mejor - de esta liga: Releases. Despues de descomprimirlo lo compilamos y lo instalamos:
$ tar xvfj vala*.bz2
$ ./configure --prefix=/usr/local
$ make
$ sudo make install


Despues se puede bajar el codigo fuente de Vala desde el repositorio - recomendable ya que agrega nueva funcionalidad y corrige bugs - con compilarlo e instalarlo:
$ svn co http://svn.gnome.org/svn/vala/trunk
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
$ make distclean
$ ./configure --prefix=/usr/local
$ make
$ sudo make install

Listo, ya podemos empezar a programar en Vala.