Sector 7G

Sector7G Live Search

About Me

About Me

Windows Live Messenger Presence Gadget

My Photo Albums

My Photo Web Albums

Logos

  • Sector7G
  • ilitia Technologies


Kartones.Net MVF Winner

August 2007 - Posts

Sintaxis LINQ: Where

Al igual que sucede en SQL, la clausula where se utiliza para filtrar el resultado de una lista de objetos.

La signatura de este operador es la siguiente:

   1:  public static IEnumerable<T> Where<T>(this IEnumerable<T> items, 
   2:  Func<T, bool> predicate);
   3:  public static IEnumerable<T> Where<T>(this IEnumerable<T> items, 
   4:  Func<T,int,  bool> predicate);

En la segunda signatura se puede observar que tiene un parámetro más. Este parámetro de tipo int nos permitirá indicar porque elemento, porque index, de la colección queremos empezar a filtrar. Esto puede resultar muy útil a la hora de paginar una colección con un número elevado de elementos. La sintaxis sería la siguiente:

   1:  void list = _developers.Where((d,index) => 
   2:      d.Language == "C#" && index >= 1);

Ejemplos

Para la realización de los ejemplos se ha utilizado el siguiente código:

   1:  public class Developer
   2:  {
   3:      public string Name { get; set; }
   4:      public string Language { get; set; }
   5:      public int Age { get; set; }
   6:  }
   7:   
   8:  public List<Developer> developers = new List<Developer> { 
   9:      new Developer{ Name="Jorge", Language="C#"},
  10:      new Developer{ Name="Pedro", Language="C#"},
  11:      new Developer{ Name="Raul", Language="VB.NET"},
  12:  };

Ejemplos 1

   1:  var list = from d in developers
   2:             where d.Language == "C#"
   3:             select new { d.Name, d.Language };

Resultado:

Jorge C#
Pedro C#

Ejemplos 2

   1:  var list = from d in developers
   2:             where d.Language == "C#" && d.Name == "Pedro"
   3:             select new { d.Name, d.Language };

Resultado:

Pedro C#

Ejemplos 3

   1:  var list = developers.Where((d, index) 
   2:      => (index >= start && index< end));

Resultado:

Pedro C#

Sintaxis LINQ: Select

Select 

Al igual que ocurre en SQL las expresiones en LinQ se componen de varios partes. Una query típica tendrá una sentencia select ( select new { d.Name, d.Language } ), la cual será aplicada a una colección de elementos ( from d in _developers ) y estará a compañada de otras serie de elementos que nos permitirán filtrar el resultado de la query ( where d.Language == "C#" ), agruparla o simplemente ordenarla.

   1:  public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source, 
   2:  Func<T, S) selector;
   3:  public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source, 
   4:  Func<T,int, S) selector;

El código anterior muestra las dos posibles signaturas del método Select, que cómo se puede apreciar se tratan de Métodos Extendidos. Todas las operaciones que se pueden realizar en una query de LinQ están desarrolladas como Métodos Extendidos. Por este motivo, podríamos realizar operaciones como las siguientes:

   1:   var list = developers.Select(d => d.Name);

Una cosa curiosa de la sintaxis de las sentencias de LinQ es que la cláusula Select se coloca al final, evidentemente esto tiene su razón de ser. Seguido a la palabra Select se definen los campos que la query tiene que devolver. Si esta cláusula se colocase al principio, el compilador no sería capaz de inferir el tipo que se está utilizando en la sentencia. Por este motivo, en primer lugar se coloca la cláusua From, la cual sí define el tipo utilizando.

   1:  var list = from d in developers 
   2:               select new { d.Name, d.Language };
   3:   
   4:  var list = from d in developers 
   5:               where d.Language == "C#" 
   6:               select new { d.Name, d.Language };

SelectMany

Si por ejemplo quisiéramos obtener todos los nombres de los proyectos en los cuales los desarrolladores de C# han trabajada podríamos hacer esto:

   1:  var list = developers
   2:      .Where(d => d.Language == "C#")
   3:      .Select(d => d.Projects);
   4:   
   5:  var list = from d in developers 
   6:              where d.Language == "C#" 
   7:              select d.Projects;

Si hacemos esto, el resultado sería una lista y cada elemento de la lista sería un array de Projects ( IEnumerable< List<Project> > ). Más o menos era lo que queríamos, pero es mucho más interesante si nos devolvira una lista con todos los Projects insertados en ella directamente ( IEnumerable< Project > ). Aquí es donde entra en juego el método SelectMany.  Las posibles signaturas de este método son las siguientes:

   1:  public static IEnumerable<S> SelectMany<T, S>(
   2:         this IEnumerable<T> source,
   3:         Func<T, IEnumerable<S>> selector);
   4:  public static IEnumerable<S> SelectMany<T, S>(
   5:         this IEnumerable<T> source,
   6:         Func<T, int, IEnumerable<S>> selector);
   7:  public static IEnumerable<S> SelectMany<T, S>(
   8:         this IEnumerable<T> source,
   9:         Func<T, IEnumerable<C>> collectionSelector,
  10:         Func<T, int, IEnumerable<S>> selector);

Para conseguir nuestro objetivo deberías desarrollar la query de una de las siguientes maneras, para así de esta forma conseguir una colección de Projects simple.

   1:  var list = developers.Where(d => d.Language == "C#")
   2:                        .SelectMany(d => d.Projects);
   3:   
   4:  var list = from d in developers 
   5:              where d.Language == "C#"
   6:              from p in d.Projects
   7:              select p;

Nota: Para la realización de estos ejemplo se han utilizado las siguientes entidades y colecciones.

   1:  public class Developer
   2:  {
   3:      public string Name { get; set; }
   4:      public string Language { get; set; }
   5:      public int Age { get; set; }
   6:      public List<Project> Projects { get; set; }
   7:  }
   8:   
   9:  public class Project
  10:  {
  11:      public string Name { get; set; }
  12:  }
  13:   
  14:  List<Developer> developers = new List<Developer> { 
  15:      new Developer{ Name="Jorge", Language="C#", 
  16:              Projects = new List<Project>{
  17:              new Project{Name= "Sector7G"},
  18:              new Project{Name= "LinQTool"}
  19:          }
  20:      },
  21:      new Developer{ Name="Pedro", Language="C#", 
  22:              Projects = new List<Project>{
  23:                      new Project{Name= "Sector7G"},
  24:                      new Project{Name= "LinQTool"} 
  25:              }
  26:      },
  27:      new Developer{ Name="Raul", Language="VB.NET", 
  28:              Projects = new List<Project>{
  29:                      new Project{Name= "BlogSite"}
  30:              }
  31:      },
  32:  };

MasterPages en Visual Studio .Net 2008

ASP.NET 2.0 ha introducido las masterpages en el desarrollo de aplicaciones, convirtiéndose en un recurso básico en el desarrollo web. Las masterpages presentaban una pequeña limitación ya que no era posible que una masterpages heredase de otra masterpage, bueno realmente si era posible, pero se pierde la vista de diseño pudiéndose convertir en un autentico infierno modificar el diseño de una página.

Error Visual Studio 2005

Visual Studio 2008 ya resuelve este problema. Haciendo posible que una masterpage herede de otra y se conserve la vista de diseño en la segunda masterpage. Mi primera masterpages, la cual contendrá el diseño común para toda la aplicación web sería la siguiente:

Masterpage 1

   1:  <%@ Master Language="C#" AutoEventWireup="true" 
   2:  CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
   3:  <html xmlns="http://www.w3.org/1999/xhtml">
   4:  <head runat="server">
   5:      <title>
   6:         Ejemplo MasterPages en Visual Studio 2008 Beta 2
   7:      </title>
   8:  </head>
   9:  <body>
  10:      <form id="form1" runat="server">
  11:          <div>MasterPage 1</div>
  12:          <div>
  13:              <asp:ContentPlaceHolder id="ContentPlaceHolder1" 
  14:                runat="server">       
  15:              </asp:ContentPlaceHolder>
  16:          </div>
  17:      </form>
  18:  </body>
  19:  </html>

Masterpage 2

   1:  <%@ Master Language="C#" MasterPageFile="~/MasterPage.master" 
   2:      AutoEventWireup="false" CodeFile="MasterPage2.master.cs" 
   3:      Inherits="MasterPage2" %>
   4:  <asp:Content ID="Content2" 
   5:      ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
   6:      <div>
   7:          MasterPage 2
   8:      </div>
   9:      <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
  10:      </asp:ContentPlaceHolder>  
  11:  </asp:Content>

Al página aspx sería la siguiente:

Dafault.aspx

   1:  <%@ Page Language="C#" MasterPageFile="~/MasterPage2.master" 
   2:      AutoEventWireup="true" CodeFile="Default.aspx.cs" 
   3:      Inherits="_Default" Title="Untitled Page" %>
   4:  <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder2" 
   5:      Runat="Server">
   6:      <p>Esta es la página por defecto.</p>
   7:  </asp:Content>

Organizando Usings en Visual Studio 2008

Otra cosa curiosa de la nueva versión del editor de código fuente de C# es la organización de Usings. Esta característica no estaba disponible en Visual Studio .Net 2005, pero herramientas como Resharper ya lo soportaban y yo personalmente la echaba de menos. Básicamente de lo que se trata es de poder borrar los usings que realmente no se utilicen en el código y de ordenarlos alfabéticamente.

Veamos un ejemplo.

   1:  using System;
   2:  using System.Text;
   3:  using System.Collections.Generic;
   4:  using System.IO;
   5:  using System.Data.Sql;
   6:  using System.Collections;
   7:  using System.Globalization;

Ordenando la lista de usings.

Ordenando Usings

   1:  using System;
   2:  using System.Collections;
   3:  using System.Collections.Generic;
   4:  using System.Data.Sql;
   5:  using System.Globalization;
   6:  using System.IO;
   7:  using System.Text;

Borrando los usings que no se utilizan en el código fuente:

Borrando Usings
    1:  using System.IO;
 
Seleccionando Framework en Visual Studio 2008

Ya me he instalado la beta 2 de Visual Studio 2008 y buscando pijadillas he encontrado una curiosa. Ahora con la nueva versión del IDE se puede seleccionar el cualquier framework que tengas instalado para compilar las aplicaciones.

Para poder seleccionar el framework sólo hay que ir a las propiedades del proyecto, ahí hay un combo donde se muestran todos los frameworks instalados en el equipo de desarrollo. Seleccionas la que más te guste y listo.

 Propiedades del proyecto

Una cosa curiosa que he visto que se puede hacer, es que diferentes proyectos de una misma solución se pueden compilen para el uso de diferentes framework. Por ejemplo, si en una solución tenemos un proyecto de consola y una librería, podríamos hacer que el proyecto de consola se compilara para el .Net Framework 3.5 y la librería para el .Net Framework 2.0. Lo compilas y evidentemente funciona correctamente, pero me parece no menos que curioso.

¿System.Web.UI.WebControls.WebParts.WebParts o Microsoft.SharePoint.WebPartPages.WebPart?
¿De que clase debe derivar un Web Part que vaya ha usarse en WSS 3.0?. La respuesta es System.Web.UI.WebControls.WebParts.WebParts, ya que el nuevo Web Part framework que se utiliza es el de ASP.NET 2.0. Esto es debido a que esta nueva versión de WSS 3.0 se sustenta sobre esta tecnología. Que ASP.NET y WSS 3.0 utilicen el mismo framework facilita que Web Parts desarrollados para ASP.NET puedan ser utilizados en los desarrollos de Sharepoint. Así la migración se facilita enormemente.

Aunque el Web Part Zone y el Web Part Manager estén específicamente implementados para Sharepoint, los Web Parts deben tener como clase base System.Web.UI.WebControls.WebParts.WebParts. 

El namespace Microsoft.SharePoint.WebPartPages.WebPart todavía se sigue utilizando para mantener la compatibilidad con Web Parts desarrollados para WSS 2.0. Sólo se debería usar en esos casos.

ASP.NET Web Parts SharePoint Backward Compatibility
WebBowsableAttribute BrowsableAttribute
WebDisplayName FriendlyName
WebDescriprion Description
Personaliyable WebPartStorage
PersonalizationScope Storage
EditorPart ToolPart
EditorPartCollection ToolPart[]
CreateEditorParts() GetToolParts()
RenderContents() RenderWebPar()
SetPersonalizationDirty() SaveProperties

Generando Documentación en .Net 2.0
Para generar documentación en .Net hay básicamente dos alternativas: Ndoc y SandCastle.

Ndoc 

Ndoc hasta la fecha se encuentra en su versión 1.3. Esta herramienta se encuentra desarrollada en la versión 1.1 del framwork de .NET, así que cuanto la vas a instalar sino tienes dicho framework te comunica que es necesario. Eso tampoco es un problema ya que en una misma máquina pueden convivir varias versiones del framework.  

El problema de Ndoc es que no soporta las versiones 2.0 y 3.0 del framework. Cuando intentas generar documentación con él, evidentemente lanza una excepción.  

Para solucionar este problema existe una versión extraoficial, se llama NDoc 2.0 Alpha. Como bien habéis deducido se encuentra en alpha. Por lo que he podido ver, lleva bastante tiempo así y no parece que vaya a cambiar la cosa. Contra todo pronóstico esta versión más o menos funciona. Yo me he visto en la obligación de usarla, por razones ajenas a mi voluntad, y funciono bien, pero bueno cualquiera se atreve.

Enlaces Ndoc
  Sandcastle 

Sandcastle viene a ser la herramienta que reemplaza a Ndoc. Actualmente esta la CTP de Junio disponible. Aporta mayor funcionalidad, como por ejemplo generar la documentación con la misma apariencia que las nuevas versiones de msnd.  

El único problema de Sandcastle es que no tiene interfaz gráfica, aunque ya existen varios proyectos para resolverlo. Uno de estos proyectos se puede encontrar en Codeplex, Sandcastle Help File Builder. 

Así que si necesitas generar la documentación de tu proyecto, esta es la herramienta de deberías utilizar. 

Enlaces SandCastle