Linq: GroupBy con múltiples campos

Exponemos aquí una necesidad ante la que seguro que os habréis encontrado; realizar una agrupación de una lista de entidades por más de un campo.

Inicialmente la función GroupBy permite hacer agrupaciones por un campo pero haciendo uso de los tipos anónimos. Simplemente debermos crear una propiedad del nuevo tipo por cada campo de agrupación.

var sums = empList.GroupBy(x => new{ x.Age, x.Sex }).Select(group => new{ Peo = group.Key, Count = group.Count() });

Espero que os sirva, salu2.

Tipos por valor Vs Tipos por referencia

Para aquellos que se inician en la programación en entorno .Net es importante conocer la diferencia entre los tipos de datos existentes y por ello hablaremos acerca de los Tipos por Valor y los Tipos por referencia.

Tipos por Valor

A este grupo pertenecen las estructuras, los enumerados y los tipos simples.

Las principales características son:

  1. Las variables declaradas de estos tipos contienen directamente el valor. Si se realiza una copia de una variable se estará duplicando el contenido a la vez.
  2. Todos los tipos por valor derivan de System.ValueType.
  3. No se pueden establecer el valor null a una variable de tipo por valor, siempre contendrá un valor de inicialización (Valores por defecto).

Tipos por Referencia

Los tipos por referencia están formados por clases, interfaces y delegados.

  1. La principal característica es que los tipos por referencia no contienen el valor de la variable sino que referencian a él. Así pues cuando se realiza una copia de una variable de tipo por referencia no se copia el contenido sino que hace referencia al mismo valor.
  2. Las variables de tipo por referencia podrán ser inicializadas con el el valor null.
  3. Para acceder a cualquiera de las propiedades de un objeto de tipo por referencia se debe haber instanciado el objeto mediante el constructor de la clase.

Veamos unos ejemplos representados mediante unos gráficos en los que se refleja lo explicado.

Tipos por valor

En el primer gráfico tenemos una variable «a» con valor 12, en el segundo paso se declara una variable «b» que se iguala a la anterior por lo tanto el valor de «b» será 12 y no el contenido de «a». Si cambiamos el valor de «a» estableciendo el valor 10 la variable «b» mantendrá el valor inicial, 12.

Tipos por referencia

En el segundo gráfico se instancia una clase «a» de tipo Clase y se establece el valor de una propiedad con el valor 12. En el tercer paso se declara una clase «b» también de tipo Clase y se iguala a la anterior, «a». El resultado es que ambas variables, «a» y «b», referencian al mismo valor, 12. Si posteriormente cambiamos el valor de la propiedad de «a» también estaremos haciéndolo sobre «b».

Para el próximo post espero poder hablar sobre los tipos de parámetros pasados a los métodos ya que está relacionado directamente con los tipos por referencia y por valor.

Salu2,

Linq: GroupBy, Sintaxis de Consulta Vs Sintaxis de Métodos

En este post vamos a ver un ejemplo sencillo de como usar la función Group By en linq sobre una lista de entidades de negocio.

Además nos servirá para ver las dos formas de consulta que nos permite Linq en .Net, Sintaxis de Consulta y Sintaxis de Métodos. Dos lenguas diferentes para expresar el mismo significado, es decir, obtendremos el mismo resultado utilizando un mecanismo u otro.

Aquí tenéis un link a la documentación al respecto en la Msdn, Msdn: Linq Query Syntax Vs Method Syntax. Utilizar una opción u otra en tus aplicaciones es cuestión de gustos, eso sí, si en la codificación interviene un equipo de desarrollo sería recomendable utilizar una única forma para mantener la uniformidad del código. Personalmente utilizaría Sintaxis de Métodos, pero como digo es una cuestión personal.

Pasemos a ver un ejemplo de como utilizar la función Group By en linq, usando Sintaxis de Consulta o de Métodos obtendremos el mismo resultado pero la sentencia varia un poquito en forma.

La query pretende obtener una lista de contenga el total de ventas por país partiendo de una lista en la que se dispone de las diferentes ventas de cada país.

Sintaxis de Métodos:

Collection <VentaPorPaisBE>  ventasPorPaisBE = new Collection <VentaPorPaisBE>();

ventasBE.GroupBy(v => v.Pais).ToList().ForEach(
group => ventasPorPaisBE.Add(
newVentaPorPaisBE() {
TotalVentasPais = group.Sum(grs => grs.TotalVentas),
Pais = group.Key}));

Sintaxis de Consulta:

Collection <VentaPorPaisBE>  ventasPorPaisBE = new Collection <VentaPorPaisBE> (
(from v in ventasBE
group v by v.Pais into g
select new VentaPorPaisBE
{
Pais = g.First().Pais,
TotalVentasPais= g.Sum(v => v.TotalVentas)
})
.ToList());

Para más información sobre la función Group By, Msdn: Linq GroupBy.

Salu2,

Métodos de extensión

Los métodos de extensión aparecieron en con la versión 3.5 del framework y nos aportan la capacidad de ampliar la funcionalidad de una determinada clase agregando nuevos métodos.

Para ello necesitamos, una clase estática con un método estático. Éste método deberá recibir como parámetro una variable cuyo tipo debe ser la clase que queremos extender precedido por el identificador this.

Veamos un ejemplo sencillo para conseguir conversiones que a veces nos hacen falta cuando trabajamos con determinadas versiones de base de datos Oracle y precisamos datos boleanos.

public static class OracleUtils
{
public static bool ToOracleBool(this string s)
{
if (s.Equals(«1»))
{
return true;
}
else
{
return false;
}
}
public static string ToOracleBoolString(this bool b)
{
if (b)
{
return «1»;
}
else
{
return «0»;
}
}
}
Una vez definidos nuestros métodos de extensión, podríamos utilizarlos sobre cualquier variable de tipo string y bool.
variableString.ToOracleBool();
variableBool.ToOracleBoolString();
Salu2

Linq: Update sobre una lista de entidades de negocio

Explotemos Linq, en este caso vemos un ejemplo de como realizar un «Update» de una propiedad de una lista de objetos mediante una sentencia.

1º Definimos una clase de negocio

public class Persona {

string Nombre:

string Apellido;

}

2º Creamos la lista de entidades

List<Persona> personas = new List<Persona>();

personas.Add(new Persona () { Nombre = «Yo»,  Apellido = «Yo»});

personas.Add(new Persona () { Nombre = «Tu»,  Apellido = «Tu»});

3º Actualizamos todas las entidades de la lista estableciendo la propiedad Nombre.

personas.ForEach(p => p.Nombre = «Nadie»);

Easy!! Salu2

Modificadores de acceso

Hola a todos,

Hoy querría hablar de los modificadores de acceso que disponemos en .net cuando nos disponemos a definir nuestras clases. Como siempre pondremos un ejemplo para abordar el tema.

Primero enumeramos los distintos modificadores:

public Acceso no restringido.
protected Acceso limitado a la clase contenedora o a los tipos derivados de esta clase.
internal Acceso limitado al proyecto actual.
protected internal Acceso limitado al proyecto actual o a los tipos derivados de la clase contenedora.
private Acceso limitado al tipo contenedor.

Información obtenida de Msdn: http://msdn.microsoft.com/es-es/library/ba0a1yw2(VS.80).aspx

Las clases definidas sin estar contenidas dentro de otras, es decir, definidas dentro de un namespace solo podrán utilizar los modificadores public e internal.

Las clases definidas como public serán instanciables desde cualquier otra clase o proyecto. En el ejemplo: OtraClase.

Internal restringe la visibilidad de una clase a aquellas que se encuentran en el mismo ensamblado o proyecto desde la que se desea instanciar. En el ejemplo: la clase B es interna del proyecto ClasesModificadores con lo que no se puede instanciar desde el proyecto Modificadores.

Por otro lado, como sabemos, dentro de una clase podemos definir a su vez nuevas clases. En este caso tendremos disponibles todos los modificadores. En el ejemplo: ClasesAnidadas.

El modificador private obliga a usar la clase dentro de la clase en la que está definido.

Protected amplia la restricción de private permitiendo usar la clase en aquellas que hereden de la contenedora.

Por último protected internal combina las dos definidas anteriormente.

Y como siempre para verlo mas clarito, usemos el ejemplo que os dejo a continuación.

Ejemplos

 Enlace para descargar el código del ejemplo: modificadores (renombrar el archivo a .zip y descomprimir).

Espero que os sirva.

Salu2, Guillermo.

Que busque como Google

¿Suena raro el título del post? Os pongo en situación.

Un nuevo proyecto software, un pliego de condiciones y una fecha de entrega. Uno de los requerimientos escrito por el cliente dice: «Que busque como Google». Así de «simple».

Pue si amigos, sorprende pero muchos de vosotros seguro que os habréis encontrado con semejantes alevosías. Y que hacer en estos casos… Desde luego la respuesta no es universal, cada compañia tiene sus formas.

Desde mi experiencia, un punto importante desde luego es realizar un documento de Alcanze del proyecto a conciencia, acotando los márgenes de lo requerido y estableciendo condiciones técnicas. La importancia de una correcta realización del Alcance del proyecto es vital para establecer puntos finales al desarrollo de los distintos módulos y funcionalidades. ¿Ustedes se imaginan el tiempo y los recursos que se necesitan para hacer «Que busque como Google»?

Salu2, Guillermo.

¿Te suena de algo Miguel?

Singleton

Después de unos cuantos días sin postear (pido disculpas) vamos a inaugurar nuestra categoría de Patrones y puesto que va a ser el primer post me gustaría hablar del archiconocido Singleton.

El patrón Singleton nos permite disponer de una sola instancia de una clase de manera que siempre que se requiera hacer uso de esta clase lo estaremos haciendo con la misma instancia. Esto nos asegura un control sobre el acceso y el consumo de memoria. Esto se consigue ocultando el constructor de la clase mediante el modicador private, para poder conseguir una instancia de la clase debermos llamar a un método estático, recordar que no tenemos contructor, y éste será el encargado de retornar una instancia de la clase. Además este método deberá ser sincronizado para evitar colisiones. Veamos un poco de código.

Como podéis ver implementar Singleton en nuestras clases es sumamente sencillo pero verdaderamente útil.

Seguiremos hablando de patrones.

Salu2, Guillermo.

Columnas calculadas

Primero un poquito de teoría:

Las columas calculadas son columnas cuyo valor será autocalculado con valores contenidos en otras columnas de la misma tabla, otras columnas calculadas, funciones o constantes aplicándoles distintos operadores.

Las el valor de las columnas calculadas se «calcula» cada vez que se consulta a no ser que se utilice la claúsula PERSISTED consiguiendo de esta manera almacenar físicamente el valor de la columna calculada. Así pues usaremos columnas calculadas sin almacenamiento físico cuando el número de consultas sea muy limitado y utilizaremos PERSISTED cuando la información vaya a ser muy consultada aunque nos penalice el aumento de espacio fisico.

Y ahora un pequeño ejemplo de cómo usar columnas calculadas en SQL Server:

Si pulsamos botón derecho sobre una tabla y seleccionamos Modificar nos llevará a la ventana de edición de columnas de la tabla. Desde aquí podemos crear una columna con el tipo de datos que deseemos y en la ventana de propiedades de la columna desplegaremos el grupo de propiedades Especificación de columna calculada y en la propiedad Fórmula introduciremos la expresión que nos calculará el valor de la columna. Si además queremos almacenar físicamente el valor de la columna calculada marcaremos True la propiedad Persistente.

Esto también se puede hacer, como no, mediante un script como el que os muestro a continuación.

CREATE TABLE Triangulos(
 Base int,
 Altura int,
 Area As Cast((Base*Altura)/2 As int)
)


Como podéis ver en el ejemplo nuestra columna calculada Area nos retornará el valor calculado del área del triangulo, del que solo almacenamos Base y Altura.

Salu2, Guillermo.

Trabajando con Proyectos de Base de datos

Vamos  a hacer un repaso de los beneficios que nos ofrece trabajar con Proyectos de Base de datos (PDB) de Visual Studio.

En primer lugar, trabajar con un PDB nos permite adjuntarlo a nuestra solución de desarrollo y así disponer de él en el entorno que ya conocemos , Visual Studio (VS), y con el que estamos acostumbrados a trabajar. De esta manera conseguimos manejabilidad y rendimiento cuando estamos trabajando.

Al ser un proyecto más de la solución también podremos gestionarlo mediante un control de código fuente, Visual SourceSafe por ejemplo. Otra ventaja, control de trazabilidad y gestión del versionado de los archivos.

Control y organización de nuestros scripts; cuantas veces os habéis vuelto locos para saber donde dejásteis aquel script que tanto os costo programar o cuanto tiempo os cuesta saber que script es la última versión, el del escritorio o el de la carpeta de Mis Documentos… No me lo negueis, esto nos ha pasado a todos. Utilizando un PBD sabemos que todos los scripts están en el PBD (o deberían si estamos trabajando correctamente).

Manos a la obra, creemos un proyecto.

Si nos vamos a VS y creamos un proyecto de base de datos (Otros tipos de proyectos\Base de datos\Proyecto de base de datos) tendremos a nuestra disposición las ventajas de las que hemos hablado.

Al crear un PBD deberemos agregar una referencia a una o varias bases de datos, todas aquellas con las que tenemos que trabajar.

Al crear el proyecto por defecto se generan las carpetas de “Change Scripts” para almacenar scripts de modificaciones sobre la base de datos, “Create Scripts” donde guardaremos scripts de creación y “Queries” para esas consultas útiles que nos gusta tener a mano. Ahora bien, esto no son más que carpetas dentro del proyecto, con lo que podemos eliminarlas y generar nuestra estructura de directorios como más nos guste; organizado por base de datos, por versión del proyecto, etc. Cada uno de los script almacenados en las diferences carpetas de nuestro PBD podremos lanzarlo contra las diferentes bases de datos que tengamos referenciadas como hemos indicado anteriormente solo con arrastrar el script con el ratón sobre la referencia de la base de datos que queramos.

Cuando queramos agregar un nuevo script al proyecto deberemos seleccionar el tipo de elemento dentro de los disponibles que son:
–         Secuencia de comandos SQL: Crea un archivo de secuencia de comandos nuevo en un bloque de texto SQL en blanco permitiendo escribir nuestro script desde cero.
–         Consulta de base de datos: Crea una nueva consulta en el Diseñador de consultas para facilitar la creación de la sentencia SQL de la consulta.
–         Secuencia de comandos de procedimiento almacenado: Crea un archivo de secuencias de comandos nuevo basado en una plantilla Procedimiento almacenado estándar.
–         Secuencia de comandos de tabla: Crea un archivo de secuencia de comandos nuevo basado en una plantilla Tabla estándar.
–         Secuencia de comandos de Desencadenador: Crea un archivo de secuencia de comandos nuevo basado en una plantilla Desencadenador estándar.
–         Secuencia de comandos de Vista: Crea un archivo de secuencia de comandos nuevo basado en una plantilla Vista estándar.

Esto es todo por hoy, espero que hayamos podido ver la potencia y la utilidad de este tipo de proyectos en VS.

Gracias y salu2, Guillermo.