Introducción a EntityFramework Core

Como todos sabemos desde el año anterior Microsoft anunció una nueva versión del .Net Framework, llamado .Net Core, una versión del framework mucho más liviana y modular, diseñada para ser multiplataforma. Uno de los productos desarrollados a la par fue EntityFramework Core, una nueva versión del ORM de Microsoft mucho más liviana la cual incluye muchas de las características implementadas en EntityFramework 6.x la última versión estable de este ORM.
El pasado 27 de Junio fue anunciada por Microsoft la liberación de la primera versión estable del .Net Core Framework o .Net Core 1.0 y consigo la liberación de Asp.Net Core 1.0 y EntityFramework Core 1.0 liberación bastante esperada por todos debido al inicio de un nuevo Framework mucho más modular y multiplataforma.
EntityFramework Core, es una versión multiplataforma, mucho más liviana y optimizada para la nube, en trabajo conjunto con Asp.Net Core, además de esto está pensado para realizar mapeos con múltiples motores de base de datos relaciones, así mismo como bases de datos no relacionales, como DocumentDB,  Azure Table Storage y Redis por ejemplo, si bien aún no tenemos estos providers en la versión actual de EF Core, se espera que sea incluida en futuras versiones.
Entre algunas de las características ya disponibles en EF Core tenemos las siguientes:
  • Fluent Api
  • DataAnnotations
  • RelationShips
  • Shadow State Properties
  • ChangeTraking
  • Optimistic Concurrency
  • Async SaveChanges
Y algunas características importantes que aún no están disponibles pero que están Backlog:
  • Lazy loading
  • Creating model from DataBase with Wizard
  • Update Model From DataBase
  • Stored Procedure Mapping
  • Connection Resiliency
Si quieres observar el listado completo de características implementadas y características por implementar en EF Core, te invito a que observes su RoadMap en la siguiente página: EF Core RoadMap.
Otro tema importante a tener en cuenta es los proveedores de base de datos que actualmente soporta EntityFramework Core, que se mencionan a continuación:
  • Microsoft Sql Server
  • SQLite
  • Postgres
  • Sql Server Compact edition
  • InMemory
  • DevArt has paid providers for MySQL, Oracle, and many other databases
Para terminar les recomiendo tener presente algunos Issues conocidos de EntityFramework Core, que aún no se han solucionado y se deben tener en cuenta, los cuales puedes encontrar en el siguiente link: EntityFramework Core Known Issues
Es una gran noticia la liberación de .Net Core, Asp.Net Core y por supuesto EntityFramework Core, sin embargo es importante tener en cuenta que son tecnologías creadas desde inicio y no una evolución de las versiones full, dado esto son tecnologías que están en proceso de maduración y aún no cuentan con muchas características, por esto es importante documentarnos a la hora de usarlos para proyectos empresariales o productivos, en próximos artículos de esta serie de EF Core observaremos nuevas características y cambios importantes con respecto a la versión 6x

Y bueno amigos con esto damos por terminado este artículo de introducción a EntityFramework Core, espero les haya resultado interesante y de utilidad.

Este artículo también lo puedes encontrar en mi blog personal: http://www.eltavo.net/2016/07/introduccion-entityframework-core.html

Saludos y buena suerte!

No inicies desde cero, Yeoman te da una mano!

Para los desarrolladores es de suma importancia a la hora de iniciar un nuevo proyecto o la construcción de una nueva aplicación tener un punto de partida que nos indique una forma ideal de estructurar nuestro código y uso de buenas prácticas, particularmente los desarrolladores que solemos usar Visual Studio para la mayoría de nuestro proyectos estamos acostumbrados a encontrar este apoyo en las diversas plantillas o starters que VS nos ofrece, pero qué pasa si nos encontramos trabajando en un entorno diferente a Windows y no contamos con VS como IDE de desarrollo?
Pues una buena alternativa sin duda es el uso de Yeoman, una popular herramienta Open source de Scaffolding web, que cuenta con un amplio sistema de generadores, los cuales permiten obtener starters para diversos tipos de proyectos en diversas tecnologías que ofrecen un buen punto de partida, si quieres indagar un poco más sobre Yeoman te puedes remitir a su sitio oficial http://yeoman.io/ y aquí puedes encontrar su código fuente https://github.com/yeoman/yeoman

 

Yeoman actualmente cuenta con 3.738 generadores, entre los cuales encontramos algunos soportados por el equipo de Yeoman y otros por la comunidad, en estos generadores podemos encontrar starters para Angular, Ionic, Asp.Net Core, BootStrap, React y muchos más. Una característica bien importante de Yeoman es que se apalanca del uso de un Task runner (Gulp, Grunt, etc) y un gestor de paquetes (Bower, npm, etc) para sacarle el mayor provecho, dado que a través de Bower por ejemplo se pueden descargar las dependencias que tienen los diferentes generadores para lograr correctamente y a través de Grunt se pueden ejecutar tareas de compilación, concatenación, minificación, servir la aplicación, etc.
Ahora que ya conocemos un poco acerca de Yeoman, vamos a ver como lo podemos usar, empecemos por instalarlo:
En primer lugar vamos a instalar NodeJs, el cual puedes descargar de la siguiente página https://nodejs.org/en/ una vez lo estés instalando observarás que se instalará por defecto también npm, el gestor de paquetes de NodeJs, el cual nos permitirá instalar posteriormente, Yeoman, Bower y Grunt.
Ahora usaremos la consola de npm para instalar Bower, que recordemos nos servirá para instalar las dependencias de los starters que usemos con Yeoman, para esto ejecutamos el siguiente comando:
$ npm install -g bower
Ahora instalaremos Gulp, que es un Task Runner al igual que Grunt, podemos usar cualquiera de los dos, en este caso instalaremos Gulp, a través del siguiente comando:
$ npm install --global gulp-cli

Y ahora a lo que vinimos, instalaremos Yeoman, a través del siguiente comando:

$ npm install -g yo

Para nuestro ejemplo vamos a crear una aplicación Asp.Net Core, por lo cual vamos a descargar su generador correspondiente, para iniciar vamos a escribir el comando “yo” en la ventana de comandos de Windows, de esta forma se nos presentarán algunas opciones a ejecutar

Si elegimos la opción instalar un generador, posteriormente nos pedirá digitar alguna palabra clave del nombre del generador para que se busque y se instale, puedes observar todos los generadores existentes y buscar más amigablemente en la siguiente página http://yeoman.io/generators/ Nosotros instalaremos directamente el generador de aplicaciones Asp.Net 5 a través del siguiente comando:

$ npm install -g generator-aspnet

Una vez termine de instalar el generador procedemos a crear nuestra aplicación Asp.Net 5 a través de este, para esto ejecutamos el siguiente comando:

$ yo aspnet

Para este generador en particular se nos preguntará que tipo de aplicación deseamos crear, aplicación de consola, Web, Web Api, etc

En nuestro caso seleccionaremos Web Application, y para finalizar debemos especificar el nombre que tendrá nuestra aplicación.

Con esto Yeoman genera la estructura de nuestro proyecto, y nos sugiere ejecutar los siguientes comandos para posicionarnos en la aplicación, restaurar los paquetes o dependencias, compilar y ejecutar respectivamente:

Si tenemos Visual Studio instalado, podemos abrir el proyecto a través de este IDE y seguirlo trabajando a través de él, pero en caso de que no lo tengamos podemos optar por los comando sugeridos anteriormente.

Como podemos ver en los comandos anteriores se hace uso de DNU y DNX, estos corresponden al .Net Execution Enviroment, que es el ambiente de ejecución que permite ejecutar las aplicaciones .Net Core, para lograr ejecutar estos comandos debemos instalar antes este entorno de ejecución, para eso usamos los siguiente comando, te recomiendo este post si quieres tener un poco más de contexto:

$ dnvm upgrade -r coreclr

Ahora que tenemos el ambiente de ejecución, ejecutaremos el siguiente comando para restaurar los paquetes o dependencias:

$ dnu restore

El siguiente comando para compilar el proyecto:

$ dnu build

Y para terminar el siguiente comando para ejecutar nuestra aplicación en un servidor local

$ dnx web

Y veremos el siguiente mensaje que nos indica en que url está corriendo nuestra aplicación para que la podamos probar:

Y si navegamos a través de un browser podremos ver nuestra aplicación corriendo con el starter por defecto de Asp.Net 5

Una vez tenemos nuestra aplicación Yeoman no nos deja solos en lo que viene, también a través de este podemos crear ítems específicos para nuestro proyecto, por ejemplo con el siguiente comando podríamos crear una nueva clase:

$ yo aspnet:Class ElTavoClase

Y bueno amigos con esto damos por terminado este artículo, sobre cómo usar Yeoman para iniciar nuestras aplicaciones, espero les haya resultado interesante y de utilidad.

Este artículo también lo puedes encontrar en mi blog personal: http://www.eltavo.net/2016/04/no-inicies-desde-cero-yeoman-te-da-una.html

Saludos y buena suerte!

How to: Utilizar SQLite con Xamarin en iOS y Android

En muchas de las aplicaciones de dispositivos móviles tenemos la necesidad de trabajar con información de forma desconectada ya que existe una buena posibilidad de que el dispositivo tenga problemas para conectarse con nuestros servicios web a falta de una conexión a internet.

SQLite es un pequeño sistema de gestión de base de datos que no depende de un servidor y que almacena nuestra información en el dispositivo de una forma más sencilla y con la ventaja de poder utilizar LINQ para realizar consultas.

Este post veremos cómo utilizarlo con Xamarin en un proyecto portable para Android y para iOS.
Como primer paso necesitamos instalar el siguiente paquete desde Nuget en cada uno de los proyectos a través de la consola de paquetes de Nuget.

Install-Package sqlite-net-pcl  

Después crearemos una interfaz a la cual llamaremos ISQLite y la cuál debe tener un solo método que se encargará de obtener la conexión al archivo desde las diferentes plataformas.

//Declaración en PCL
public interface ISQLite  
{
   SQLiteConnection GetConnection();
}

Ahora debemos hacer la implementación dentro de nuestros proyectos, iniciemos por Android donde debemos colocar el siguiente código.

//Implementación en android
public class SQLite : ISQLite  
{
   public SQLiteConnection GetConnection()
   {
       string documentPath =
             Environment.GetFolderPath(Environment.SpecialFolder.Personal);

       string libraryPath = Path.Combine(documentPath, "..", "Library");

       Directory.CreateDirectory(libraryPath);

       var path = Path.Combine(libraryPath, CommonKeys.FileName);

       return new SQLiteConnection(path);
   }
}

Además, debemos agregar el siguiente atributo a nivel de namespace para utilizar los servicios de dependencia.

[assembly: Dependency(typeof(SQLite))]

Ahora veamos la siguiente implementación dentro del proyecto de iOS.

//Implementación en iOS
public class SQLite : ISQLite  
{
   public SQLiteConnection GetConnection()
   {
       string documentPath =
             Environment.GetFolderPath(Environment.SpecialFolder.Personal);

       string libraryPath = Path.Combine(documentPath, "..", "Library");

       Directory.CreateDirectory(libraryPath);

       var path = Path.Combine(libraryPath, CommonKeys.FileName);

       return new SQLiteConnection(path);
    }
}

Es necesario también agregar el siguiente atributo a nivel de namespace para poder utilizar también los servicios de dependencia.

[assembly: Dependency(typeof(SQLite))]

Ahora he creado un pequeño contexto para crear nuestra base de datos y además para obtener la conexión haciendo uso de los servicios de dependencia de Xamarin.

 public class DataBaseContext
 {
   public bool CreateDataBase()
   {
     try
     {
        using (var connection = GetConnection())
        {
            //Debes crear aquí cada una de las tablas que necesites
            connection.CreateTable<LicensePlate>();
         }
      }
      catch (Exception)
      {
          return false;
      }
      return true;
   }

   public SQLiteConnection GetConnection()
   {
      //Obtienes la implementación del contrato
      return DependencyService.Get<ISQLite>().GetConnection();
   }
}

Después crearemos un pequeño repositorio (debes modificarlo a tus necesidades) para poder realizar nuestras operaciones con los datos además de asegurarnos que nuestras operaciones sean thread safe.

//Repositorio en PCL
public class PlateRepository : IPlateRepository  
{
    private readonly DataBaseContext dataBaseContext;
    private static object locker = new object();

    public PlateRepository(DataBaseContext dataBaseContext)
    {
        this.dataBaseContext = dataBaseContext;
    }

    public IEnumerable<LicensePlate> LicensePlates => GetAll();

    public void Add(LicensePlate licensePlate)
    {
       lock (locker)
       {
          using (var connection = dataBaseContext.GetConnection())
          {
             connection.Insert(licensePlate);
          }
        }
    }

    public void Update(LicensePlate licensePlate)
    {
      lock (locker)
      {
         using (var connection = dataBaseContext.GetConnection())
         {
            connection.InsertOrReplace(licensePlate);
         }
      }
    }

    public void Delete(int id)
    {
       lock (locker)
       {
          using (var connection = dataBaseContext.GetConnection())
          {
             var item = connection.Table<LicensePlate>().FirstOrDefault(p => p.Id == id);
             if (item != null)
             {
                connection.Delete(item);
             }
          }
       }
    }

    public IEnumerable<LicensePlate> GetAll()
    {
       lock (locker)
       {
          using (var connection = dataBaseContext.GetConnection())
          {
              return connection.Table<LicensePlate>().ToList();
          }
       }
    }
}

Ahora podremos almacenar información en nuestros dispositivos, solo debes tener en cuenta que en algunas ocasiones estas operaciones consumen recursos y debes mantenerte al pendiente de la optimización de los recursos.

¿Cuéntame cuál ha sido tu experiencia con SQLite?

¡Saludos!

How to: Ocultar la barra de navegación y la barra de estatus en iOS y Android

En algunas ocasiones por cuestiones de diseño se requiere quitar la barra de navegación nativa en nuestra aplicación así como la barra de estatus.

Eliminar la barra de navegación en Xamarin no requiere de mucho esfuerzo, solo debes agregar la siguiente línea de código en el constructor de tus páginas.

 NavigationPage.SetHasNavigationBar(this, false);

Para ocultar la barra de estatus en iOS necesitas abrir el archivo info.plist y agregar los siguientes tags al archivo.

<key>UIStatusBarHidden</key>  
<true/>  
<key>UIStatusBarHidden~ipad</key>  
<true/>  
<key>UIViewControllerBasedStatusBarAppearance</key>  
<false/>  

Y en Android necesitas crear un estilo en el archivo Resources\values\Styles.xml parecido al siguiente:

<style name="MyTheme" parent="@android:style/Theme.Holo.Light">  
<item name="android:windowFullscreen">true</item>  
<item name="android:actionBarSize">0dp</item>  
</style>  

Y después asignar este estilo en el atributo Activity en MainActivity.cs

[Activity(Theme = "@style/MyTheme")]

Deseando te resulte útil este pequeño tip, me despido
¡Saludos! @saturpimentel

Dapper vs EntityFramework, debo usar un MicroOrm o un Orm?

En muchos de nuestros proyectos hemos usado un Orm para lograr mapear nuestro modelo de datos a nuestros objetos y estructura de clases de nuestra aplicación, logrando con esto resolver el acceso y persistencia de datos sin mucho esfuerzo y poder enfocarnos en lo que verdaderamente nos importa, el dominio del negocio.
Los Orm han tomado mucha fuerza y actualmente son usados en la mayoría de aplicaciones dado las facilidades y bondades que ofrecen, Orms como Nhibernate, EntityFramework, Hibernate, Telerik Data Access, son ejemplos de Orms bastante populares y usados en la actualidad, debido a las facilidades que ofrecen y buenas prácticas y patrones que encapsulan.

Pese a esto siempre se ha discutido con respecto al rendimiento que estos nos ofrecen y cómo pueden afectar el desempeño de nuestras aplicaciones, debido a las facilidades y funcionalidades que ofrecen se vuelven bastante robustos para preparar y acceder a la información. Por ejemplo EntityFramework está basado sobre la arquitectura de Ado.Net lo cual sugiere que tenemos una capa intermedia, que obtiene el resultado a través de los componentes de este y posteriormente mapea el resultado a un objeto de nuestra aplicación, este proceso sugiere algunos milisegundos más en cada transacción.

Ahora, que pasa si tuviéramos una alternativa un poco más liviana y rápida que sacrifique algunas facilidades y características para garantizar el rendimiento en el acceso a datos? pues de esto se trata un MicroOrm, este nos permite realizar un mapeo de nuestro modelo relacional a objetos de nuestra aplicación, solo que lo hace de una forma más simple y sin algunas características como por ejemplo manejo de relaciones entre tablas, manejo de concurrencia, cargas por demanda, diseñador del modelo, etc.

Entre los MicroOrm más famosos encontramos los siguientes:

  • PetaPoco
  • Insight
  • NPoco
  • Dapper (Se puede decir que este es el MicroOrm más conocido y usado, debido a que se ha comprobado que es el que mejor rendimiento tiene, tan solo un milisegundo más que una consulta directamente con Ado.Net, adicional este es el MicroOrm usado por el reconocido foro StackOverflow, para soportar su robusta arquitectura)

Ahora que ya conocemos que es un micro Orm y sabemos cuál es su principal diferencia con un Orm, vamos a ver cómo funciona y cómo es su implementación, para esto vamos a usar Dapper, y adicional vamos a realizar una serie de comparaciones de rendimiento y de codificación con EntityFramework.

Para nuestro ejemplo vamos a usar la conocida base de datos Northwnd, la cual puedes descargar del siguiente enlace: https://northwinddatabase.codeplex.com/

Posteriormente vamos a crear en Visual Studio un nuevo de proyecto de tipo consola y en la clase Program, vamos a empezar a codificar el ejemplo.

Para iniciar vamos a abrir la consola del administrador de paquetes Nuget y vamos a ejecutar el siguiente comando para instalar el paquete de Dapper:

Install-Package Dapper -Version 1.42.0

Y hacemos el Using del NameSpace Dapper en la clase Program, con esto se agregan una serie de métodos de extensión a la clase SqlConnection las cuales nos permiten usar el MicroOrm para interactuar con la base de datos.

Para la conexión a la base de datos a través de Dapper solo necesitamos especificar la cadena de conexión, para esto crearemos una constante en clase Program en la cual la almacenaremos, para efectos de nuestro ejemplo vamos a usar cadenas mágicas en el código y no archivos de configuración, dado que esto no es relevante para el ejercicio:

private const string Cadena = "Initial Catalog=NORTHWND;Data Source=TAVOPC;Integrated Security=SSPI;";

Escenario de una consulta simple a una sola tabla

Ahora vamos a codificar nuestro primer escenario, en el cual vamos a consultar en la tabla Ordenes, a través de Dapper y vamos a mapear el resultado a la entidad Orden (entidad creada por nosotros)

private static void ConsultarOrdenesDapper()
{
    using (IDbConnection db = new SqlConnection(Cadena))
    {
        var consulta = @"SELECT [OrderID] AS Id, [CustomerID] AS IdCliente, [EmployeeID] AS IdEmpledo,
                    [OrderDate] AS Fecha, [RequiredDate] AS FechaRequerida, [ShipCountry] AS Pais, [ShipCity] AS Ciudad
                    FROM [NORTHWND].[dbo].[Orders]";
 
        var stopwatch = new Stopwatch();
        stopwatch.Start();
 
        // Se ejecuta la consulta.
        var ordenes = db.Query<Orden>(consulta);
 
        stopwatch.Stop();
        System.Console.WriteLine("Dapper.Net: {0} registros obtenidos en {1} milisegundos.", ordenes.Count(),
          stopwatch.ElapsedMilliseconds);
    }
}

Como podemos ver es bastante sencillo usar Dapper, en este caso a través de la clase SqlConnection establecemos la conexión con la base de datos, y ejecutamos el método Query, especificando el tipo en el que queremos obtener el resultado de la consulta, cabe mencionar que el método Query no se encuentra en la clase SqlConnection por defecto, este es un método de extensión agregado por el Nuget de Dapper. Ahora invocaremos el método ConsultarOrdenesDapper desde el método Main de la clase program, y ejecutamos el programa para ver los resultados.

Como podemos apreciar obtenemos un resultado bastante óptimo de 856 registros en 4 milisegundos, ahora en cuánto tiempo resolverá EntityFramework esta consulta? pues vamos a averiguarlo.

Para crear nuestro modelo conceptual a través de EntityFramework, vamos a usar el enfoque “Code First From DataBase” el cual permite usar CodeFirst con una base de datos existente y crea el contexto y las entidades a partir de ella, observa aquí un tutorial detallado acerca de cómo usar este enfoque: CodeFirst From DataBase

Ahora que ya tenemos nuestro contexto vamos a codificar la misma consulta que realizamos con Dapper, pero esta vez la ejecutaremos a través de EntityFramework.

private static void ConsultarOrdenesEf()
{
    using (var contexto = new NorthwndModel())
    {
      var stopwatch = new Stopwatch();
      stopwatch.Start();
 
      var ordenes = contexto.Orders.ToList();
 
      stopwatch.Stop();
      System.Console.WriteLine("EntityFramework: {0} registros obtenidos en {1} milisegundos.", ordenes.Count,
      stopwatch.ElapsedMilliseconds);
    }
}

Ahora de igual forma vamos a invocar el método ConsultarOrdenesEf desde el método main de la clase Program, y ejecutamos de nuevo la aplicación para ver el resultado:

Pues la diferencia es bastante grande de 6 milisegundos de Dapper a 95 milisegundos de EntityFramework, sin lugar a dudas es una diferencia significativa, si bien 95 milisegundos siguen siendo poco esos milisegundos van sumando en cada transacción, y en una aplicación de alta demanda por ejemplo sí que se notarían y afectarían muy negativamente el rendimiento.

Ahora que hemos realizado este primer escenario comparativo podemos concluir que definitivamente el rendimiento de Dapper es muy superior al de EntityFramework, dado que como había mencionado antes el MicroOrm es muy rápido y liviano, por el contrario el Orm es bastante robusto y ofrece muchas más extensiones y funcionalidades que penalizan un poco el rendimiento. Sin embargo si analizamos y comparamos detenidamente el código de cada una de las implementaciones podemos decir que la implementación de EntityFramework es mucho más limpia, trazable y mantenible, otro aspecto muy importante en nuestras aplicaciones. Adicional vale la pena considerar el escenario en el cual trabajamos con tablas relacionadas, escenario que encontraremos en todas nuestras aplicaciones y que veremos a continuación.

Escenario de consulta a dos tablas relacionadas

Sin duda una de esas características que brilla por su ausencia en los MicroOrm con respecto a los Orm, es el manejo de relaciones entre entidades de una forma sencilla y objetual, obviamente el Micro Orm no tiene esto entre sus prioridades, pero si que hace falta. Para plantear este escenario vamos a realizar una consulta en la tabla ordenes y en la tabla ordenes detalle, en un escenario Eaguer, es decir donde necesitamos obtener la información en una sola consulta a la base de datos y no por demanda, vemos como sería la implementación con Dapper:

private static void ConsultarOrdenesDetallesDapper()
{
            var consulta = @"SELECT a.[OrderID] AS Id
	                    ,a.[CustomerID] AS IdCliente
	                    ,a.[OrderDate] AS Fecha
                          ,b.[ProductID] AS IdProducto
                          ,b.[UnitPrice] AS Precio
                          ,b.[Quantity] AS Cantidad
                          ,b.[Discount] AS Descuento
                      FROM [NORTHWND].[dbo].[Order Details] b
                      INNER JOIN [NORTHWND].[dbo].[Orders] a
                      ON a.OrderID = b.OrderID;";
 
            using (IDbConnection db = new SqlConnection(Cadena))
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
 
                // Se ejecuta la consulta.
                var ordenesDetalle = db.Query<DetalleOrden>(consulta);
 
                stopwatch.Stop();
                System.Console.WriteLine("Dapper.Net: {0} registros obtenidos en {1} milisegundos.",
                    ordenesDetalle.Count(), stopwatch.ElapsedMilliseconds);
            }
}

De la implementación anterior podemos observar que se hace una consulta involucrando las dos tablas y se traen todos los registros de ambas, es decir se repiten los registros de la tabla ordenes por cada registro asociado en la tabla ordenesDetalle, y debido a esto se creó la entidad DetalleOrden, lo cual es una implementación que no nos permite orientar correctamente a objetos, ya que deberíamos tener la entidad orden y la entidad detalle separadas y cargarlas con la data, esto se debe a que el MicroOrm no permite manejar las relaciones y esta es una solución al escenario que planteamos de carga total. Ahora veamos como logramos la misma implementación pero usando EntityFramework.

private static void ConsultarOrdenesDetallesEf()
{
      using (var contexto = new NorthwndModel())
      {
         var stopwatch = new Stopwatch();
         stopwatch.Start();
 
         var ordenesDetalle = contexto.Orders.Include("Order_Details").ToList();
 
         stopwatch.Stop();
         .Console.WriteLine("EntityFramework: {0} registros obtenidos en {1} milisegundos.",
         ordenesDetalle.Count, stopwatch.ElapsedMilliseconds);
      }
}

De nuevo podemos observar a simple vista que la implementación con EntityFramework es mucho más limpia y orientada a objetos, hacemos una consulta sobre la tabla Ordenes y especificamos que se incluyan los datos de la tabla relacionada o propiedad de navegación Order_Details, de esta forma se obtienen los registros:

Todos los datos en sus respectivas entidades de una forma objetual, ahora veamos el rendimiento de cada de una de las implementaciones:

Sigue existiendo una diferencia abismal en el rendimiento de las consultas, y ahora que EntityFramework está gestionando las relaciones ha aumentado sustancialmente, dado que debe mapear las entidades y cada registro de las entidades de una forma anidada.

Escenario de inserción en una sola tabla

Ahora vamos a ver un par de escenarios en los cuales no consultaremos información si no que la guardaremos, para observar cómo se comportan tanto el MicroOrm como el Orm, veamos la implementación para Dapper y para EntityFramework:

private static void InsertarOrdenDapper()
{
    var consulta =
                $@"INSERT INTO [NORTHWND].[dbo].[Orders] (CustomerID, OrderDate) 
                    VALUES ('VINET', '{DateTime.Now.ToString("yyyy-MM-dd")}');";
    using (IDbConnection db = new SqlConnection(Cadena))
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
 
        // Se ejecuta la instrucción.
        db.Execute(new CommandDefinition(consulta));
 
        stopwatch.Stop();
        System.Console.WriteLine("Dapper.Net: un registro insertado en {0} milisegundos.",
        stopwatch.ElapsedMilliseconds);
    }
}

 

private static void InsertarOrdenEf()
{
    using (var contexto = new NorthwndModel())
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
 
        var orden = new Order
        {
            CustomerID = "VINET",
            OrderDate = DateTime.Now
        };
 
        contexto.Orders.Add(orden);
        contexto.SaveChanges();
 
        stopwatch.Stop();
        System.Console.WriteLine("EntityFramework: un registro insertado en {0} milisegundos.",
                    stopwatch.ElapsedMilliseconds);
    }
}

Como podemos ver dos implementaciones muy sencillas en Dapper y en EntityFramework para insertar un registro, ahora comparemos el rendimiento de ambas implementaciones:

En este escenario de inserción de un solo registro nos damos cuenta que en este aspecto la diferencia de rendimiento entre Dapper y EntityFramework no es tan grande, solo 7 milisegundos una diferencia en tiempo realmente pequeña.

Escenario de inserción en dos tablas relacionadas

Para terminar la comparación entre Dapper y EntityFramework vamos a ver el último escenario en el cual vamos a insertar información en dos tablas relacionadas, veamos entonces como es el código a implementar para cada tecnología:

private static void InsertarOrdenDetalleDapper()
{
      var consulta =
        $@"INSERT INTO [NORTHWND].[dbo].[Orders] (CustomerID, OrderDate) 
        VALUES ('VINET', '{DateTime.Now.ToString("yyyy-MM-dd")}') select SCOPE_IDENTITY();";
      using (IDbConnection db = new SqlConnection(Cadena))
      {
          var stopwatch = new Stopwatch();
          stopwatch.Start();
 
          // Se almacena la orden y se obtiene su Id Identity.
          var idOrden = (int)db.Query<decimal>(consulta).First();
 
          consulta = $@"INSERT INTO [NORTHWND].[dbo].[Order Details] 
          VALUES ({idOrden}, 41, 20, 100, 0);";
          db.Execute(new CommandDefinition(consulta));
 
          stopwatch.Stop();
          System.Console.WriteLine("Dapper.Net: registros relacionados insertados en {0} milisegundos.",
          stopwatch.ElapsedMilliseconds);
      }
}

 

private static void InsertarOrdenDetalleEf()
{
    using (var contexto = new NorthwndModel())
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
 
        var orden = new Order
        {
            CustomerID = "VINET",
            OrderDate = DateTime.Now,
            Order_Details =
            {
                new Order_Detail
                {
                    ProductID = 41,
                    UnitPrice = 20,
                    Quantity = 100,
                    Discount = 0
                }
            }
        };
 
        contexto.Orders.Add(orden);
        contexto.SaveChanges();
 
        stopwatch.Stop();
        System.Console.WriteLine("EntityFramework: registros relacionados insertados en {0} milisegundos.",
        stopwatch.ElapsedMilliseconds);
    }
}

Como podemos observar en este último escenario para EntityFramework creamos un solo objeto, especificando la información para la entidad padre y también para para la propiedad de navegación y EntityFramework se encarga de ejecutar las dos instrucciones de inserción, por el contrario con Dapper se debe ejecutar en primera instancia la instrucción para la tabla padre y obtener su Id, para posteriormente ejecutar la instrucción de la tabla relacionada, ahora observemos el desempeño de ambas implementaciones:

Como en el escenario anterior vemos que la diferencia no es muy significativa, cuando se trata de operaciones de inserción. Dados los anteriores escenarios podríamos concluir que Dapper tiene un rendimiento muy superior a EntityFramework en cuanto a consulta de datos se refiere, sin embargo en operaciones de inserción tienen un rendimiento muy similar. También podemos concluir que usando un Orm podemos lograr implementaciones mucho más limpias y objetuales y un código más mantenible.

En resumidas cuentas podemos concluir que los Micro Orm nos permiten practicidad, simplicidad y óptimo rendimiento, sacrificando un poco la mantenibilidad y orientación a objetos, mientras que los Orm nos permiten mejor mantenibilidad y orden sacrificando un poco el rendimiento, elegir uno u otro siempre dependerá del escenario que estemos resolviendo y según lo requieran nuestro atributos de calidad, recordemos que en el desarrollo de software no existen las balas de plata, y ambas tecnologías pueden ser muy válidas en determinados escenarios.

Y bueno amigos con esto damos por terminado el artículo, espero que esta comparación entre Dapper y EntityFramework les haya resultado interesante y de utilidad.

El código fuente lo puedes descargar de mi repositorio en GitHub.

Saludos, y buena suerte!

How to: Crear Azure Mobile Apps

Azure está mejorando los actuales Mobile Service dando mayores características a estos y los ha renombrado como Mobiles Apps, que son parte de la nueva oferta integrada de Azure App Services en este post vamos a ver cómo crear un Mobile App en el nuevo portal de Azure, pero antes una breve descripción.

¿Qué son las Mobile Apps?

Las Mobile Apps ofrecen alta escalabilidad, disponible a nivel mundial para plataformas de desarrollo empresariales.

Entre las ventajas de las Mobile Apps se listan las siguientes:

  • Puedes construir aplicaciones nativas y cross-platform.
  • Conectado a su sistema empresarial.
  • Permite conectarse a las APIs SaaS de manera sencilla.
  • Permite construir aplicaciones offline con sincronización.
  • Permite enviar notificaciones Push a millones en segundos.

Ahora veamos cómo crear Mobile Apps en el portal de Microsoft Azure, en primer lugar y como son servicios nuevos los podremos encontrar en el nuevo portal de Azure, después damos clic en el símbolo + -> Web + Mobile ->Mobile App después proporcionaremos un nombre al subdominio del Mobile App, seleccionaremos la suscripción, seleccionaremos o crearemos un nuevo grupo de recursos y la localización del App Service.

Ahora crearemos una nueva conexión con una nueva base de datos.

Seleccionaremos crear una nueva base de datos y asignaremos un nombre a la base de datos, así como un tamaño de instancia y podemos cambiaremos lacollation de ser necesario, después de proporcionar todos los datos pasaremos a configurar nuestro servidor.

En esta sección asignaremos un subdominio para nuestra base de datos, así como un usuario y contraseña para acceder al servidor, después tendremos que seleccionar la ubicación de nuestro servicio dentro de los servidores de Azure como se muestra en la siguiente imagen.

Después de que Azure genere nuestro servicio es necesario modificar la cadena de conexión de nuestra Mobile App proporcionando nuestro usuario y contraseña para que nuestro back-end tenga acceso a nuestra base de datos.

Al finalizar todos estos pasos tendrás acceso a un Quick Started donde podrás descargar un back-end web inicial y un conjunto de códigos de ejemplo de los diferentes tipos de proyectos que soportan Mobile Apps tal como se muestra en las siguientes figuras.

Conclusión

Ahora es más sencillo crear nuestro back-end de datos utilizando Azure Mobile Apps ya que se ha simplificado el proceso de creación y agregado muchas más características, de algunas de ellas hablaremos más adelante.

En el siguiente post veremos como crear nuestro back-end con ASP.Net utilizando EF code first para exponer nuestros datos por medio medio de servicios REST.

Espero te resulte útil y no olvides suscribirte a la lista de correos.

¡Saludos!

Desarrollo de aplicaciones con Windows 10 en Telmexhub

Ya se está haciendo una de mis costumbres estar cada mes en TelmexHub :P.
Esta vez he estado con Amin Espinoza y Raúl Guerrero en un curso de introducción a Windows 10 en el que hemos mostrado como crear nuestra primer UWP App.

Aquí les dejo el vídeo del evento.

Y algunas fotos

¡Saludos!

¿Por qué esperar? SignalR y Mobile Services para mensajes en tiempo real

En estas últimas semanas he estado trabajando en una aplicación que tiene un sistema de envío de mensajes, para estos mensajes se ha utilizado SignalRpara mejorar la velocidad de entrega y vaya que es rápida la conexión y el envío de mensajes.

La aplicación a la que me refiero tenía un backend con Mobile Services el cual ya ofrece un Azure Service Bus que utilizamos como backplane para la distribución de los mensajes.

Este es un post con un breve ejemplo de cómo enviar mensajes entre las aplicaciones, como primer punto vamos a definir que es SignalR.

¿Qué es SignalR?

SignalR es una biblioteca open source desarrollada por miembros del equipo de ASP .Net y que nos sirve para conectar aplicaciones en tiempo real de una manera muy sencilla, SiganlR nos provee una capa de abstracción que nos permite utilizar diferentes transportes que inicia por Web Sockets y en caso de no ser soportados hace un proceso de fallback entre los diferentes tipos de conexión que soporta.

El proceso de fallback a grandes rasgos sería el siguiente, primero intentaría conectar por web sockets, en caso de no poder conectarse lo intentará conServer Sent Events, Forever Frames y Long Pollig sucesivamente hasta lograr una conexión.

Una de las características principales de SignalR es que nos permite simular una conexión persistente en el caso del HTTP y administra la conexión con web sockets que sí soportan una conexión persistente.

SignalR nos da también la habilidad de hacer “push” desde el servidor hacia el cliente, evitando que el cliente tenga que realizar conexiones al servidor para validar si existe nueva información, SignalR evita esto permitiendo al servidor realizar callback a los clientes.

Creando nuestro primer Signalr Hub

Lo primero que haremos es instalar los paquetes de Nuget que nos darán acceso a las características de SignalR en nuestro servidor.

Para esto iremos a la consola de Nuget y agregaremos la siguiente línea.

Install-Package WindowsAzure.MobileServices.Backend.SignalR  

Una vez hemos agregado los paquetes a nuestro proyecto Web podemos crear nuestro hub, en este ejemplo crearemos un método que nos permita enviar un mensaje a todos los clientes conectados.

[HubName("ChatHub")]
    public class ChatHub : Hub
    {
        public ApiServices Services { get; set; }

        public void Send(string message)
        {
            Clients.All.helloMessage(message);
        }
    }

Nota: Clients.All no es la única manera en la que podemos enviar mensajes, también tenemos Caller, Others, AllExcept, etc. te invito al leer el siguiente post para más información.

Después en el archivo WebApiConfig agregaremos el siguiente código para iniciar los servicios de SignalR.

public static class WebApiConfig  
    {
        public static void Register()
        {
           //Initialize SignalR
           SignalRExtensionConfig.Initialize();            
        }
    }

Conectando nuestra aplicación

Ahora agregaremos los paquetes de Nuget para habilitar los servicios deSignalR en el cliente, como podrás notar en este ejemplo utilizaremos una aplicación universal.

Agrega la siguiente línea en la consola de Nuget.

Install-Package Microsoft.AspNet.SignalR.Client  

Una vez se instalen los paquetes agregaremos el siguiente código para conectarnos con los servicios de SignalR.

private IHubProxy proxy;  
private HubConnection hubConnection;

private async Task ConnectToSignalR()  
{
   //Se crea el hub utilizando la url de nuestro Mobile Service
   hubConnection = new HubConnection(App.MobileService.ApplicationUri.AbsoluteUri);  

   //Agregamos en los headers la llave de Mobile Service, de lo contrario no nos permitirá realizar la conexión 
   hubConnection.Headers["x-zumo-application"] = App.MobileService.ApplicationKey;

   //Creamos un proxy para conectarnos con el hub de chat que hemos creado previamente
   proxy = hubConnection.CreateHubProxy("ChatHub");
   // Iniciamos la conexión
   await hubConnection.Start();

   //Utilizaremos el método On para recibir la notificación cada vez que se utilice el mensaje "helloMessage".
   proxy.On<string>("helloMessage", async (msg) =>
   {
      await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
      {
         message += " " + msg;
         Message.Text = message;
      });
   });
}

Al navegar a la página conectaremos con el hub.

 protected override async void OnNavigatedTo(NavigationEventArgs e)
 {          
    await ConnectToSignalR();
 }

Después agregaremos el siguiente código en un botón para enviar información desde nuestra app y no solo recibir.

private async void Button_OnClick(object sender, RoutedEventArgs e)  
{
   //Utilizaremos el método invoke cuando deseemos enviar un mensaje desde nuestra aplicación
   await proxy.Invoke<string>("Send", TextBox.Text);
   TextBox.Text = string.Empty;
}

Escalando con Azure Service Bus

En este caso al utilizar Mobile Service y tener un nivel de servicio básico o estándar (como es el caso que he platicado anteriormente) te tengo una buena noticia, ya tenemos habilitado Azure Service Bus para sincronizar nuestra entrega de mensajes en los clientes sin importar cuantas instancias tengamos trabajando. ¡Excelente! ¿No te parece?
La siguiente es una imagen que explica cómo funciona SignalR en conjunto con Azure Service Bus.

Nota: Azure Service Bus a pesar de ser un muy buen servicio no es el único con el que puedes trabajar ya que SignlR te permite trabajar también con Redis y con SQL Server.

Ahora ya podemos enviar mensajes en tiempo real a través de nuestras aplicaciones.

Te dejo él código del proyecto de ejemplo en github, como siempre espero te resulte útil y no olvides compartir.

¡Saludos!

How to: Encontrar elementos duplicados con IEqualityComparer y el método Except de LinQ

Dando una vuelta por stackoverflow he visto una pregunta en la cual deseaban obtener los elementos de una colección siempre y cuando los identificadores no coincidieran con los de una segunda colección y que no se realizaran modificaciones a su entidad, la clase que proponían como ejemplo es la siguiente.

public class Employee  
{
  //EmployeeNumber cannot be the same as the Id
  public int EmployeeNumber {get; set; }
  public string EmployeeName {get; set }
}

Nota: recuerda que las clases personalizadas son tipos por referencia y los objetos aun cuando contengan los mismos datos no tienen la misma referencia en memoria (es decir Equals para este escenario no es una opción).

Pensando un poco y tomando en cuenta que lo que las colecciones estaban en memoria les he sugerido implementar la interfaz IEqualityComparer < T > y el método Except< T >.

La interfaz IEqualityComparer nos permite comparar dos objetos de una manera sencilla y con las condiciones que nosotros queramos,IEqualityComparer contiene los siguientes dos métodos:

  • public bool Equals(Employee x, Employee y) Este método nos va a permitir determinar si el objeto es igual.
  • public int GetHashCode(Employee x) Va a retornar un código hash para el objeto en específico.

Pues bien, como el problema que se ha planteado al inicio necesitaba comparar los identificadores la implementación de la interfaz ha quedado de la siguiente manera (puedes adaptarla a tus necesidades).

public class MyComparer : IEqualityComparer<Employee>  
{
    public bool Equals(Employee x, Employee y)
    {
        return x.EmployeeNumber.Equals(y.EmployeeNumber);
    }

    public int GetHashCode(Employee x)
    {
        return x.EmployeeNumber.GetHashCode()
    }
}

Una vez tenemos nuestra implementación podemos hacer uso del métodoExcept de LinQ y obtener los elementos de nuestra lista sin tomar en cuenta los que tengan el mismo identificador de la segunda lista, algo que en teoría de conjuntos es conocido como la diferencia.

Tendrías que implementar un código parecido al siguiente:

IEnumerable<Employee> except =list1.Expect(list2,new MyComparer());  

Hasta aquí este post corto, espero les resulte de utilidad.
¡Saludos!

Hola UWP: Detectar la familia de dispositivos

Con Windows 10 podemos crear una sola aplicación y hacer que esta se ejecute en diferentes dispositivos, con esta diversidad de dispositivos es probable que se piense que se limita la funcionalidad, pero no es así ya que las aplicaciones UWP cuentan con APIs y herramientas específicas para cada familia de dispositivos que nos permiten crear experiencias únicas.

En este post vamos a ver como reconocer a cada una de las diferentes familias, para ello vamos a crear un nuevo proyecto y en el MainPage.xaml.cs vamos a agregar la siguiente referencia.

using Windows.System.Profile;  

Después vamos a agregar una propiedad que va a contener un mensaje con el nombre de la familia a la que pertenece el dispositivo la cual vamos a obtener a través de la propiedad DeviceFamily de la clase VersionInfo.

public string DeviceFamily = $"La familia del dispositivo es:{AnalyticsInfo.VersionInfo.DeviceFamily}";  

Entre los posibles resultados que arrojará esta propiedad se listan los siguientes:

  • Windows.Desktop
  • Windows.Mobile
  • Windows.Xbox
  • Windows.IoT

Por último vamos a utilizar un atado de datos con x:Bind para vincular la propiedad con el TextBlock y listo podemos ejecutar nuestro aplicación y saber en qué familia de dispositivos se esta ejecutando nuestra aplicación.

<StackPanel>  
    <TextBlock Text="¡Hola UWP!" FontSize="24" FontWeight="Light" Margin="12" />
    <TextBlock Text="{x:Bind DeviceFamily}" Margin="12,0,0,0" />
</StackPanel>  

Ahora podemos conocer a que familia pertenece el dispositivo donde se está ejecutando nuestra aplicación y hacer los cambios que consideremos necesarios, espero les resulte útil ¡Saludos!