LINQPad y la ventana de comandos (en Finanzas.Net)

febrero 21, 2011 13:38 by LuscoTekhne

Muchas veces necesitamos saber cómo se va a comportar una línea de código o un pequeño método (si va a devolver null o un tipo inicializado por defecto, si va a cumplir una determinada condición o no).  En Microsoft Visual FoxPro (esa magnífica evolución del lenguaje dBase cuyo soporte finalizará en 2015 – v. http://msdn.microsoft.com/es-es/vfoxpro/bb308952) la ventana de comandos cumplía a las mil maravillas esa función puesto que permitía, en tiempo real, crear variables, invocar métodos e, incluso, examinar el comportamiento de las sentencias en el depurador.

Recuerdo que esta era, precisamente, una de las cosas que más echaba de menos cuando en Lusco comencé a usar C# como lenguaje de programación.  Intenté usar la ventana Inmediate del depurador de Microsoft Visual Studio, pero tenía dos inconvenientes....

 Entrada en el blog Finanzas.Net de Paulino Martínez


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Nuevo Módulo xTrela.Mobile: un ERP en la palma de tu mano

enero 31, 2011 18:34 by XanSalgado

Nuevo Módulo xTrela.Mobile del ERP xTrela:

Aporta movilidad y ofrece funcionalidad complementaria a nuestro ERP utilizando dispositivos portátiles con lector de códigos de barras y wifi.

Funcionalidades: Validaciones de Etiquetado/Código de barras de artículos (con transmisión de fotos de productos), Cierre de envíos, Control de albaranes, Conteo para inventario...

Operativa on-line (wi-fi) contra los servidores centrales o desconectada con descarga de datos en el dispositivo móvil (para ser usado en zonas sin cobertura wi-fi).

Disponible para dispositivos Windows Mobile 5, 6.0, 6.5 (Motorola MC50, MC55, MC70, Intermec...)  

http://www.lusco.eu/solutions


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Por fin nuestro visor de fotos Silverlight

diciembre 23, 2010 20:03 by LuscoTekhne

Tras arduas peleas con Silverlight y Expression Blend 4, comenzamos a tener versiones que funcionan.

Es un visor sencillo que amplía automáticamente (con alguna animación) una foto de la lista de contactos (o la que seleccione el usuario). Con una lista de controles, una lista de imágenes y un par de storyboards encadenados ya está. Lo más difícil: conseguir reutilizar un storyboard para distintos elementos según la selección del usuario.

http://www.lusco.eu/labs/PhotoViewer/

Ya tenemos algún otro prototipo que publicaremos próximamente.

 ¿Windows Phone 7 será nuestro siguiente reto?.


Actualmente calificado con 4.0 por 1 personas

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Como hacer un WCF Service con Streaming

junio 8, 2010 13:11 by eugenioestrada

Haciendo pruebas esta mañana he mirado como hacer un servicio en WCF por Streaming y es bastante sencillo.

Lo que debemos hacer es configurar nuestro servicio modificando su binding en el Web.Config

<bindings>
  <basicHttpBinding>
    <binding name="HttpStreaming" maxReceivedMessageSize="67108864"
              transferMode="Streamed"/>
  </basicHttpBinding>
</bindings>

Una vez que lo tengamos ya podemos hacer que nuestras operaciones devuelvan o reciban un objeto de tipo Stream. Por un lado modificamos el contrato de nuestro servicio:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    Stream GetData();
}

Y por otro lado el método.

public class Service1 : IService1
{
    public Stream GetData()
    {
        StringBuilder sb = new StringBuilder();

        for (long i = 0; i < 10; i++)
        {
            sb.AppendLine("Prueba" + i.ToString());
        }
 
        var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));

        return stream;
    }
}

Con esto en el cliente también recibiremos un Stream y con un StreamReader podríamos leer su contenido.

Espero sea útil.


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Paralelizando tareas

junio 2, 2010 09:45 by eugenioestrada

Cada vez son más los equipos que al menos tienen dos núcleos, ahora mismo ya tenemos algunos con cuatro que emulan ocho. Pero no estamos, como desarrolladores, explotando ese potencial.

Imaginaros que tenemos en memoria una lista con cientos de miles de objetos y debemos realizar alguna operación sobre ellos, como cambiar un valor. Nosotros haríamos algo similar a:

foreach (var objeto in lista)
{
    objeto.dato = nuevoValor;
}

Esta instrucción sería equivalente a hacer:

for (int i = 0; i < lista.count; i++)
{
    var objeto = lista[i];
    objeto.dato = nuevoValor;
}

Estas instrucciones tendrían una complejidad O(n), pero solo harían uso de un solo núcleo.

Si estamos usando .NET 4.0, éste nos trae de serie una serie de funciones para paralelizar trabajos y de tal forma que va a repartir las tareas en diferentes núcleos.  No solo eso, sino que si un núcleo tiene capacidad para n tareas también se le pondrán n tareas a él.

Para hacer eso tan solo hay que cambiar un poco la llamada anterior:

lista.AsParallel().ForEach (objeto =>
{
    objeto.dato = nuevoValor;
});

El resultado final es que durante el proceso de ese bucle el procesador se pondrá al 100%, pero la tarea será ejecutada en menos tiempo.

Algunas consideraciones sobre paralelismo:

Debemos tener en cuenta que al realizar un trabajo en paralelo tenemos principalmente tres problemas:

  • Dividir el problema
  • Sincronizar las tareas
  • Unir el problema de nuevo

Todo esto tiene el problema de que supone una carga computacional extra que solamente será “rentable” si el bucle es muy grande. De todas formas en caso de que fuese pequeño debería ser imperceptible estas operaciones, ya que la carga computacional será pequeña de todas formas.


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Deshabilitar el analizador de Resharper en un fichero o parte de él.

marzo 18, 2010 12:09 by marcossanchez

Resharper es una herramienta imprescindible en el desarrollo de aplicaciones con Visual Studio. Sin embargo, hay situaciones en las que tenemos archivos demasiado grandes y el analizador de Resharper puede tardar una eternidad en procesar el fichero, o dar incluso una OutOfMemoryException. Para solucionarlo, podemos:

  • Crear una Region con un nombre especial para que Resharper no analice su contenido
    • En el menú de opciones de Resharper, en la opción Settings, podemos usar como nombre de la Region uno de los que aparecen en la lista, o añadir un elemento nuevo.
  • Deshabilitar el analizador para ficheros concretos:
    • Podemos hacerlo pulsando [Ctrl+8] o en el menú de opciones de Resharper, en la opción Settings, boton Advanced…

Actualmente calificado con 3.0 por 1 personas

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Despliegue distribuido de clientes en .NET problemas y futuro

octubre 28, 2009 00:22 by eugenioestrada

Desde la beta 1 de Visual Studio 2010 llevo testeándolo, pero aun no me había atrevido a escribir nada. Pero esta mañana leí una cosa que me pareció bastante interesante.

Para aquellos que tenemos aplicaciones distribuidas usando .NET 3.5 SP1 tenemos bastantes problemas a la hora de la distribución o inclusión de nuevos clientes.

Estos problemas derivan de que .NET 3.5 SP1 es una recopilación de bastantes actualizaciones partiendo de .NET 2.0 como base:

image

Lo que supone instalar 6 actualizaciones acumulativas, esto sobre una instalación base de XP sin .NET. Sobre todo la última actualización .NET 3.5 SP1 se hizo más pesada de lo habitual. Ya que incluía parches para el .NET 2.0, para el .NET 3.0 y para .NET 3.5. Ya que aun que en el gráfico yo lo puse en ese orden, no fue ese el orden real de publicación, ya que el .NET 2.0 SP2 y el .NET 3.0 SP2 fueron publicados junto al .NET 3.5 SP1 y durante un tiempo solo se podían instalar con el .NET 3.5 SP1 (el gráfico de publicación lo podéis ver a continuación).

image

Esto supuso un gran problema. Si nosotros nuestro proyecto de .NET 2.0 (con Visual Studio 2005) lo migrábamos a Visual Studio 2008 SP1 (liberado junto a .NET 3.5 SP1) y compilábamos con .NET 2.0, realmente estaría compilando con .NET 2.0 SP2 y en nuestros clientes no funcionaría. El problema se vio agravado ya que el paquete de .NET 2.0 SP2 no estuvo disponible hasta 6 meses después de la liberación de .NET 3.5 SP1. Cosa que obligaba instalar en todos los clientes el monumental .NET 3.5 SP1 (que ocupaba 3 veces más que su original 2.0). No solo eso, la instalación de dicho paquete se hacía eterna (aproximadamente entre 45 min y 1 hora dependiendo de la máquina). Esto en una máquina, ni en diez, es problema. Pero si hablamos de un sistema distribuido con un número considerable de clientes, si que podría ser un problema, sobre todo garantizando el funcionamiento del sistema durante la implantación y su mantenimiento.

Otra solución posible sería el planteamiento del uso del Client Profile de .NET Framework, que es una versión reducida para clientes distribuidos. Pero, solo era posible la opción si partíamos de una instalación limpia (sin .NET) y solo disponible en XP (ya que Windows Vista trae consigo .NET 3.0 y Windows 7 tiene .NET 3.5 SP1).

Pero .NET 4.0 tiene grandes novedades en su .NET Framework 4 Client Profile. Como gran novedad, al contrario que su antecesor, se puede instalar en cualquier SO y plataforma donde .NET 4 Framework esté soportado. Siendo Client Profile un subset de .NET 4 completo y el .NET 4 completo es un superset del primero. No solo eso, además han conseguido reducir el Client Profile a un distribuible de apenas 30 MB, incluyendo las tecnologías más comunes de los clientes como Windows Forms o WPF. Por otra parte, Visual Studio 2010 Beta 2 en sus proyectos de escritorio tiene por defecto el Client Profile activado.

Siendo esta la tabla comparativa (extraída de un post de Scott Guthier):

 

 

.NET Framework 4 Client Profile (NEW)

.NET Framework 3.5 SP1 Client Profile

Supported OS

Supported on all platforms and  OSs that are supported by the .NET Framework (excluding IA64 and the Server Core role in W2K8)

Supported only on Windows XP 32-bit machines that did not have any .NET Framework version installed.

(Client Profile setup silently installs the full 3.5 SP1 Framework otherwise)

Redistributable

Supports redistributable as well as web download

Supports web download only

Add Remove Programs entries

The full Framework comprises the Client Profile and another part called “Extended”. Thus it has two entries in the Add/Remove Programs dialog (or Programs and Features window).

If you installed the Full Framework, you can switch to the Client Profile by simply removing “Extended” from Add/Remove Programs.

Single entry in Add Remove Programs

Visual Studio

Improved support for Client Profile targeting in Visual Studio 2010.

By default many Visual Studio 2010 Beta2 Client project target the NET4 Client Profile.

Single checkbox in Visual Studio 2008 Service Pack 1 “Application” Project properties for .NET Framework 3.5 projects. Client Profile support unavailable in out-of-the-box VS 2008.

Features

Includes new .NET 4  features (such as Managed Extensibility Framework (MEF), C# 4 Dynamic Keyword,etc) as well as features previously included in NET 3.5 SP1 Full (Speech, WPF Spell Check, etc)

Subset of features in .NET 3.5 SP1 Full

Espero que os sea útil e interesante :-)

Follow me: http://twitter.com/eugenioestrada


Actualmente calificado con 3.0 por 2 personas

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Problemas y soluciones: Entity Framework, vistas y claves

junio 8, 2009 17:30 by eugenioestrada

Uno de los grandes problemas que me he encontrado a la hora de trabajar con Entity Framework (EF) es la de mapear una vista.

¿Dónde está el problema?

El problema está que una entidad de EF debe tener una clave primaria y las vistas no tienen claves primarias.

image

En una vista como la anterior realmente no tenemos una clave definida en la base de datos ya que los datos filtrados por Entidad generaría una gráfica como la siguiente:

image

Por defecto EF infiere que Entidad es una clave, lo infiere a partir de aquellos campos que SQL Server dice que no pueden ser nulos. En principio no da ningún problema, pero tenemos dos casos en los que ya encontramos conflictos.

  1. Obtenemos más de un resultado con Entidad idéntica. Al rellenar los objetos EF, presupone que al tener la misma clave primaria son el mismo objeto por lo que siempre tendríamos el primer objeto creado.
  2. Si filtramos por Entidad exclusivamente, EF presupone que solo vendrá un resultado por lo tanto se produce una excepción.

Hasta aquí bien, la solución podría ser quitar esa clave, EF no nos deja:

“Toda entidad tiene que tener una clave primaria”

¿Solución?

Para ello debemos de crear una clave artificial, el rowcount de nuestra vista puede ser una opción, ya que todas las claves deben ser distintas. Pero como aun así nuestro Entity Framework no lo detecta como clave debemos emergernos en el EDMX y modificar el XML a mano.

Para ello cabe destacar que el fichero XML tiene un elemento llamado <edmx:Runtime> que es el que a nosotros nos interesa y que éste consta de tres partes:

  1. SSDL: StorageModels: El modelo importado de la base de datos
  2. CSDL: ConceptualModels: El modelo generado a partir del importado y el que representará cada una de las entidades que luego usaremos por código
  3. C-S: Mappings: Es la que une ambos modelos

Nosotros primero debemos modificar el SSDL, el siguiente es el :

<EntityType Name="vXXXX">
  <Key
    <PropertyRef Name="Entidad" /> 
  </Key
  <Property Name="IDPK" Type="bigint" /> 
  <Property Name="Entidad" Type="int" Nullable="false" /> 
  <Property Name="FechaPrevista" Type="datetime" /> 
  <Property Name="Sobres" Type="int" />
</EntityType>

Este sería el modelo importado tal cual lo importó el diseñador. Como veis hemos creado el campo IDPK con el rowcount para establecerlo como clave. Para poder hacerlo se debe de hacer lo siguiente:

 

<EntityType Name="vXXXX"
  <Key
    <PropertyRef Name="IDPK" /> 
  </Key
  <Property Name="IDPK" Type="bigint" Nullable="false" /> 
  <Property Name="Entidad" Type="int" /> 
  <Property Name="FechaPrevista" Type="datetime" />
  <Property Name="Sobres" Type="int" />
</EntityType>

Entonces en el modelo de la base de datos ya tenemos IDPK como clave. Ahora solo nos queda cambiarlo en el diseñador. Y para ello debemos hacer click derecho en el campo y establecerlo como clave:

image 

Y así ya podremos trabajar normalmente con nuestra entidad.

Problemas posteriores

Problemas tendremos después cuando actualicemos el modelo desde la base de datos, porque el SSDL se modificará y tendremos que hacer a mano los cambios que ahora hemos hecho. En cambio en el diseñador no tendremos que hacer nada.


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Operaciones de datos con DataServices vs Custom WCF Services

abril 21, 2009 10:44 by albertobasalo

ADO.Net DataServices facilita el desarrollo N-Tier de aplicaciones que se apoyen en ADO.Net Entity Framework, exponiendo una fachada de servicios CRUD que mediante una interface REST muy sencilla de usar. Para mayor comodidad dispone de librerías cliente para llamar a esa interfaz y consultarla mediante LINQ.

Los programadores pueden extender la funcionalidad básica del servicio mediante métodos interceptores, como el siguiente, en el que validamos o completamos la entidad antes de la operación :

[ChangeInterceptor("Fichas")]
public void OnChangeFichas(Ficha ficha, UpdateOperations action)
{
    try
    {
        switch (action)
        {
            case UpdateOperations.Add:
                Logic.Fichas.Validate(ficha);
                ficha.IdFicha = Logic.Fichas.GetNewGUID();
                break;
            case UpdateOperations.Change:
                Logic.Fichas.Validate(ficha);
                break;
        }
    }
    catch(Exception ex)
    {
        throw new DataServiceException("No se ha podido realizar la operacion", ex);
    }
}

Esto puede ser suficiente en muchos casos, pero también tiene limitaciones. Al ser métodos sin valor de retorno nos dificulta la obtención del estado del objeto posterior a la ejecución, por ejemplo no dispondríamos del GUID en el cliente. Además este interceptor se ejecuta antes de la operación y no ofrece ningún evento a posteriori, esto impide llamar a lógicas de negocio en el servidor que se ejecuten transaccionalmente con la operación o después de esta.

Por el contrario los servicios WCF ofrecen flexibilidad total tanto en funcionalidad como en infraestructura, a costa de un poco más de código y una configuración mas tediosa.

El ejemplo anterior puede resolverse con los siguientes métodos:

public Ficha AddFicha(Ficha ficha)
{
    try
    {
        Logic.Fichas.Validate(ficha);
        ficha.IdFicha = Logic.Fichas.GetNewGUID();
        using (var context = new Context())
        {
            context.Attach(ficha);
            context.SaveChanges();
        }
        return ficha;
    }
    catch (Exception ex)
    {
        Log.Excepcion(ex);
        throw new FaultException("No se ha podido agregar la ficha por " + ex.Message);
    }
}

Para actualizar entidades se usa un método extensor que asegure que la entidad inicialmente desatachada se persista en base de datos, según explica Cesar De La Torre en su blog

public Ficha UpdateFicha(Ficha ficha)
{
    try
    {
        Logic.Fichas.Validate(ficha);
        using (var context = new Context())
        {
            context.Attach(ficha);
            ficha.SetAllModified(context);
            using (var transaction = context.Connection.BeginTransaction())
            {
                context.SaveChanges();
                Logic.Fichas.PostProcess(ficha);
                transaction.Commit();
            }
        }
        return ficha;
    }
    catch (Exception ex)
    {
        Log.Excepcion(ex);
        throw new FaultException("No se ha podido actualizar la ficha por " + ex.Message);
    }
}

En fin, una vez mas .Net ofrece alternativas para un mismo fin y depende de las circunstancias el elegir la más directa o la más flexible.

Agradecimiento  especial a los consultores de Plain Concepts cuyos conocimientos sobre arquitectura de software y tecnologías Microsoft son apabullantes. Espero vuestros comentarios.

Actualmente calificado con 4.0 por 1 personas

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

ajax: cómo crear nuestro propio UpdateProgress

agosto 24, 2008 13:44 by EugenioEstrada

A veces no queremos hacer uso del UpdateProgress que viene con ASP.NET por diversos motivos.

Objetivo

image El objetivo es conseguir el efecto del UpdateProgress. Para ello necesitamos un UpdatePanel donde tengamos por ejemplo un botón con un Label. Para que el efecto sea visible se recomienda usar el método Sleep de System.Threading.Thread, un par de segundo es suficiente.

Requisitos

Cualquier versión de ASP.NET AJAX nos sirve, tanto la 1.0 (para .NET 2.0) descargable en http://ajax.asp.net/, como la versión nativa de ASP.NET AJAX. Si usas VS 2008 (o Visual Web Developer 2008 Express Edition) no tendrás que descargar nada.

Análisis

¿Que hace el UpdateProgress? Siempre que se hace una petición al servidor se muestra un panel. Por lo que ya sabemos dos cosas:

  1. Debemos manejar el evento de comienzo y finalización de las peticiones en el cliente.
  2. Hay algo oculto que debemos mostrar después.

Esta claro que el lenguaje en el cliente es JavaScript y para el estilo (necesario para mostrar y ocultar el panel, que ya digo que será una capa, DIV) usaremos estilso en cascada CSS.

Coding.

Antes de nada el manejador de evento del evento Click del botón es:

protected void ActualizarButton_Click(object sender, EventArgs e)

{

    HoraLabel.Text = DateTime.Now.ToShortTimeString();

    System.Threading.Thread.Sleep(5000);

}

Ahora vamos a la parte que nos ocupa, el cliente. La capa que nos ocupa es la siguiente, sencillita:

<div id="updateProgress" class="hidden">

    Actualizando...

</div>

Como puedes ver vamos a tener un estilo llamado hidden y, esto os lo digo yo, tendremos otro para cuando lo queramos mostrar, que le llamaré showed, estos son los siguientes:

.hidden {

    display: none;

}

.showed {

    border: 2px solid #FF0000;

    background-color: #FF6666;

    color: #800000;

    font-size: x-large;

    font-family: Arial, Helvetica, sans-serif;

    padding: 10px;

    margin: 10px;

    width: 200px;

    text-align: center;

}

Le he añadido algo de formato en el estilo showed, para que se vea bien. Realmente lo importante es la diferencia de que el primero contiene la etiqueta display: none y la segunda no.

Bien, ahora nos queda lo más importante, manejar los dos eventos en el cliente. La clase encargada de ello es el PageRequestManager, en el namespace Sys.WebForms. Y el código es tan sencillo como este:

function pageLoad() {

    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginPageRequest);

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endPageRequest);

}

 

function beginPageRequest(sender, args) {

    updateProgress.className = "showed";

}

 

function endPageRequest(sender, args) {

    updateProgress.className = "hidden";

}

En este caso el efecto es muy similar al del UpdateProgress, pero los resultados pueden ser muy diversos cuanto más lo piensa uno.

http://www.lusco.eu/blog


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5