[.NET] Myo Armband & MyoSharp .ft HackSpacePeru

Enlaces

CodePlex

Código fuente disponible en: CSharp -> MyoHackNighter

[.NET] ¿Cómo saber si un número es primo?

Hoy compartiré un simple algoritmo que nos permitirá saber si algún número es primo o no.

C#

using System;

namespace PrimeNumber.WindowsConsole
{
internal class Program
{
private static void Main(string[] args)
{
for (var i = 1; i <= 50; i++)
{
if (!IsPrimeNumber(i)) continue;

Console.WriteLine();
Console.WriteLine(string.Format("TABLA DEL {0}", i));
for (var j = 1; j <= 12; j++)
Console.WriteLine(string.Format("{0} x {1} = {2}", i, j, i * j));
}

Console.Read();
}

private static bool IsPrimeNumber(int number)
{
var root = Math.Sqrt(number);
if (root % 1 == 0)
return false;

var limit = Math.Ceiling(root);
for (int i = 2; i <= limit; i++)
if (number % i == 0 && number != 2)
return false;

return true;
}
}
}

CodePlex

Código fuente disponible en: CSharp -> PrimeNumber.WindowsConsole

[.NET] ¿Cómo almacenar palabras en un archivo de texto?

Hoy aprenderemos algo muy sencillo, algo que nos puede ser útil cuando queramos guardar logs por ejemplo.

C#

using System;
using System.IO;

namespace ConsoleTextWriter
{
public class Program
{
private const string _path = "frases.txt";

private static void Main(string[] args)
{
if (File.Exists(_path))
Console.Write(File.ReadAllText(_path));

ReadAndSaveConsoleLine();
}

private static void ReadAndSaveConsoleLine()
{
var line = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(line))
{
using (var streamWriter = new StreamWriter(_path, true))
streamWriter.WriteLine(line);
ReadAndSaveConsoleLine();
}
}
}
}

CodePlex

Código fuente disponible en: CSharp -> ConsoleTextWriter

[WPF] ¿Como generar un Código QR y exportarlo en PNG?

En la presente publicación ejemplificaré como lograr estos objetivos ayudándonos de una librería llamada QrCode.Net la cual esta disponible para WinForms (no lo he probado) y WPF. Para este post he usado la versión 0.3 porque la 0.4 es Pre-release.

Con esta librería hay un par de formas de hacer esto: usando el control QrCodeControl o la clase QrEncoder.

QrCodeControl

Lo único que hay que hacer acá es dibujarlo correctamente en el XAML e ir actualizando su propiedad Text.

<Window x:Class="GenerateQR.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:qr="clr-namespace:Gma.QrCodeNet.Encoding.Windows.WPF;assembly=Gma.QrCodeNet.Encoding"
Title="[C#] ¿Cómo generar un Código QR y exportarlo en PNG?" Height="350" Width="525">
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtCode" Margin="6" TextChanged="txtCode_TextChanged"/>
<Button x:Name="btnExport" Grid.Column="2" Content="Exportar PNG" Margin="6" Click="btnExport_Click"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<qr:QrCodeImgControl Grid.Column="0" Margin="6" x:Name="qrControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto" />
<Image Grid.Column="1" x:Name="imgQR" />
</Grid>
</Grid>
</Window>
        private void txtCode_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtCode.Text)) return;

//QrCodeImgControl
qrControl.Text = txtCode.Text;
}

QrEncoder

Para usar esta clase primero tenemos agregar las referencias a System.Drawing, PresentationCore y WindowsBase. Una vez agregadas las referencias continuamos:

        private Bitmap GetQRBitmap(string content)
{
var qrEncoder = new QrEncoder();
var code = qrEncoder.Encode(content);
var bitmapImage = new Bitmap(code.Matrix.Width, code.Matrix.Height);

for (int j = 0; j < code.Matrix.Height; j++)
for (int i = 0; i < code.Matrix.Width; i++)
bitmapImage.SetPixel(i, j, code.Matrix[i, j] ? System.Drawing.Color.Black : System.Drawing.Color.White);

return bitmapImage;
}

private BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();

return bitmapimage;
}
}

private void txtCode_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtCode.Text)) return;

//Image
var imageSource = BitmapToImageSource(GetQRBitmap(txtCode.Text));
this.imgQR.Width = imageSource.PixelWidth;
this.imgQR.Height = imageSource.PixelHeight;
this.imgQR.Source = imageSource;
this.imgQR.UpdateLayout();
}

Exportando el PNG

Aquí nos valemos de la clase PngBitmapEncoder y en este ejemplo estoy exportando el archivo en la misma carpeta del ejecutable para ser simples.

        private void btnExport_Click(object sender, RoutedEventArgs e)
{
string path = Guid.NewGuid().ToString() + ".png";

using (FileStream fileStream = new FileStream(path, FileMode.Create))
{
PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
pngBitmapEncoder.Frames.Add(BitmapFrame.Create((WriteableBitmap)qrControl.Source));
pngBitmapEncoder.Save(fileStream);
fileStream.Close();
}
}

CodePlex

Código fuente disponible en: CSharp -> GenerateQR

[.NET] ¿Cómo usar Enterprise Library 6 Data Access Application Block usando solo código?

En una publicación pasada mostré como usar EntLibDAAB configurándola usando el .config. En esta ocasión enseñaré como usar este componente usando solo C#.

Para esta demostración usé cualquier procedimiento almacenado que devuelva datos (en este caso dbo.uspGetEmployeeManagers) de una base de datos muy conocida llamada Adventure Works y un proyecto WPF con la siguiente class y DataGrid para mostrar los datos.

SqlDatabase

La primera forma de trabajar con EntLib6DAAB y SQL Server es usando directamente Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase y pasándole como argumento la cadena de conexión.

DatabaseSettings

Si queremos tener un mayor control sobre la configuración podemos usar Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings


Si queremos usar alguna otra base de datos con EntLib como Oracle o MySQL tenemos que agregar nuevas entradas a ProviderMappings o si queremos establecer alguna base de datos por defecto no olvidemos hacer lo siguiente:

CodePlex

Código fuente disponible en: CSharp -> EntLib6DAABInCode

[.NET] Integrando objetos de .NET en SQL

La integración CLR es una característica que nos permite ejecutar código manejado en SQL Server. El código manejado es más adecuado que Transact-SQL para los cálculos y la lógica de ejecución complicada y presenta una amplia compatibilidad para muchas tareas complejas, como son el tratamiento de cadenas, fechas, expresiones regulares, etc.

Primer paso

En un nuevo proyecto del tipo Class Library (o librería de clases) definimos una clase con un par de métodos estáticos:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IntegrandoCLR
{
public class SpecialMath
{
public static void Procesar(int a, int b, out int c)
{
if (a > b)
c = a + b;
else
c = a * a;
}

public static double Calcular(double a, double b)
{
return Math.Log(a, b);
}
}
}

Segundo paso

Una vez construida la librería y ubicada en algún lugar del disco, hacemos lo siguiente en SQL Server:

--Habilitamos la carácterística a nivel de servidor.
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

--Registro el ensamblado con algún nombre (este ensamblado queda disponible para todas las bases de datos en el servidor)
CREATE ASSEMBLY MiSuperEnsamblado
FROM 'D:IntegrandoCLR.dll'
GO

--Creo el procedimiento almacenado asociándolo con el método estático en la clase
CREATE PROCEDURE ProcesarConSpecialMath_SP
@Num1 INT,
@Num2 INT,
@Num3 INT OUTPUT
AS EXTERNAL NAME MiSuperEnsamblado.[IntegrandoCLR.SpecialMath].Procesar
GO

--Creo la función asociándola con la función estática en la clase
CREATE FUNCTION ClacularConSpecialMath_FN(@Num1 FLOAT, @Num2 FLOAT)
RETURNS FLOAT
AS EXTERNAL NAME MiSuperEnsamblado.[IntegrandoCLR.SpecialMath].Calcular
GO

Fin

Ya hecho todo esto podemos probarlo de la siguiente manera:

DECLARE @Result INT
EXEC ProcesarConSpecialMath_SP 77,9, @Result OUT
PRINT @Result
GO

SELECT dbo.ClacularConSpecialMath_FN(3,9)
GO

[.NET] Enterprise Library Data Access Application Block

Enterprise Library Data Access Application Block es una API desarrollada por Microsoft, la cual facilita en muchas maneras el trabajo que tiene que realizar un programador para implementar una capa de Acceso a Datos.
En el siguiente video se explicaran sus fundamentos y se hará una demostración de como configurar las versiones 5 y 6 de esta API,además de realizar una demostración de como usarla.

Config v5:

Config v6:

Links:

[.NET] Enviar correos con System.Net.Mail

Aveces nos es necesario enviar correos desde alguna de nuestras aplicaciones, esto se puede lograr de muchas maneras, una de ellas por ejemplo seria usar el Database Mail del SQL Server, pero en esta ocasión se hara usando 2 clases que se encuentran en el namespace System.Net.Mail que son SmtpClient y MailMessage. Es una demo sencilla, basta entender la idea y se pueden hacer muchísimas cosas.

    class Program
{
static void Main(string[] args)
{
EnviarCorreo();
}

private static void EnviarCorreo()
{
//Configurando el cliente SMTP
SmtpClient client = new SmtpClient();
client.Host = "smtp.gmail.com";
client.Port = 587;
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("correoOrigen@gmail.com", "clavecorreoOrigen");
//Preparando archivo adjunto
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("Contenido de un documento de texto muy interesante."));

//Enviando correo
MailMessage mail = new MailMessage();
mail.From = new MailAddress("correoOrigen@gmail.com");
mail.To.Add(new MailAddress("correoDestinatario@gmail.com"));
mail.Subject = "Correo simple de HTML con documento adjunto.";
mail.IsBodyHtml = true;
mail.Body = "<h2>Hola!</h2><br/><br/>Visiten: <a href='http://xamldevelopment.blogspot.com'>XAML Development</>";
mail.Attachments.Add(new Attachment(ms,"Documento.txt"));
client.Send(mail);
}
}

Actualización: 14 Abril 2014

Otra forma de configurar uno o más SmtpClient es usando el App.config o Web.config.

¿Cómo configurar un SmtpClient desde el .config?

Simplemente agregamos el siguiente código XML al nodo principal <configuration>:

App.config o Web.config

  <system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="correoOrigen@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen@gmail.com" password="clavecorreoOrigen" />
</smtp>
</mailSettings>
</system.net>

CSharp

SmtpClient client = new SmtpClient();

Bastaría hacer lo anterior en C# y apreciar que los valores por defecto son los mismos que hemos establecido en el .config.

¿Cómo configurar más de un SmtpClient desde el .config?

En este caso debemos definir un section con su type por cada SmtpClient que queramos usar (en el ejemplo pondre 3), agruparlos en un sectionGroup (el cual llamaré mailingConfiguration, puede tener cualquier otro nombre) y luego establecer correctamente los valores (no es necesario que todos tengan el mismo clientDomain). Entonces, agreguemos el siguiente código XML al nodo principal <configuration> sin olvidar que configSections debe ser el primer elemento del nodo configuration sino no funcionaria:

App.config o Web.config

<configSections>
<sectionGroup name="mailingConfiguration">
<section name="cliente1" type="System.Net.Configuration.SmtpSection"/>
<section name="cliente2" type="System.Net.Configuration.SmtpSection"/>
<section name="cliente3" type="System.Net.Configuration.SmtpSection"/>
</sectionGroup>
</configSections>

<mailingConfiguration>
<cliente1 deliveryMethod="Network" from="correoOrigen1@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen1@gmail.com" password="clavecorreoOrigen1" />
</cliente1>
<cliente2 deliveryMethod="Network" from="correoOrigen2@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen2@gmail.com" password="clavecorreoOrigen2" />
</cliente2>
<cliente3 deliveryMethod="Network" from="correoOrigen3@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen3@gmail.com" password="clavecorreoOrigen3" />
</cliente3>
</mailingConfiguration>

CSharp

SmtpSection smtpSection = (SmtpSection)ConfigurationManager.GetSection("mailingConfiguration/cliente1");
SmtpClient smtpClient = new SmtpClient();
smtpClient.Host = smtpSection.Network.Host;
smtpClient.Port = smtpSection.Network.Port;
smtpClient.EnableSsl = smtpSection.Network.EnableSsl;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = smtpSection.Network.DefaultCredentials;
smtpClient.Credentials = new NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password);

Si bien estamos mapeando propiedad por propiedad desde el smtpSection la ventaja es que ahora lo tenemos todo centralizado desde el .config, no olviden agregar la referencia a System.Configuration.

Eso es todo amigos :)!

[.NET] Entity Framework 5 & .NET

Para empezar, recordemos que EF es una ORM (Object Relational Mapping), que en palabras simples es una herramienta de Microsoft .NET que nos permite trabajar con nuestra data en base a un modelo conceptual en vez de tener que interactuar con la data directamente, se basa en el Dominio y no en  la Base de Datos, Conexiones o Procedimientos.

Entity Framework 

Entity Framework permite a los desarrolladores despreocuparse por el mantenimiento y la codificación necesaria para poder interactuar con cualquier base de datos relacional (Oracle, SQL, MySQL, etc) con un proveedor de datos EF válido.

Inicialmente Entity Framework dependía estrictamente de .NET, pero es a partir de Entity Framework 4.1 en que se separo relativamente, esto quiere decir que aunque todavía se construye sobre .NET, el ciclo de evolución de Entity Framework es independiente al de .NET.

Entity Framework se puede implementar en 3 formas distintas y haciendo simples descripciones: Code First (Si existen clases y no prefieres el diseñador visual), Model First (Si no existe la base de datos y prefieres el diseñador visual) y Database First (Si existe la base de datos y prefieres el diseñador visual). Ahora solo falta decir que en la implementación de Code First, EF5- no soporta la definición de Store Procedures propios para la persistencia de nuestra data con los métodos Insert, Update y Delete.

Rendimiento en Entity Framework 5

Desde la primera versión de Entity Framework, la clase CompiledQuery permitía a los desarrolladores pre-compilar las sentencias Linq para poder mejorar el rendimiento, ya que sin esto cada vez que se ejecutaba Linq, Entity Framework tenia que convertirlo a T-SQL.

Mas usar CompiledQuery tenia 2 grandes inconvenientes, el primero es que se tenia que definir explícitamente qué sentencias se iban a pre-compilar y la segunda era de que no había manera de usar CompiledQuery en DbContext. A esto se suma que si tu estas usando el modelo Code First, lo más probable es que estés usando DbContext y también que Microsoft recomienda que se deberia usar DbContext en nuevos proyectos incluso si estas trabajando con Database First o Model First. En otras palabras, usar CompiledQuery se volvía algo inusual y desconocido.

Entity Framework 5 nos trae auto-compiled queries o auto-cached queries (entiendase lo mismo) lo cual hace que nuestro código Linq se resuelva muy diferente ya que Entity Framework guarda implícitamente en cache el T-SQL generado. Entonces cada vez que se va a ejecuta Linq lo que se hace antes de generar el T-SQL es buscar si existe en cache el T-SQL correspondiente y se utiliza.

Actualizando a Entity Framework 5 & .NET 4.5

Si por algún motivo se empezó a usar EF4 ó EF5 con .NET 4 y se desea hacer un upgrade a EF5 con .NET 4.5 hay que tomar muy en cuenta que las versiones de las .dll referenciadas son diferentes. Entonces cambiar el Target framework del proyecto a .NET 4.5 no es suficiente, ya que la .dll del EntityFramework no se actualiza y hay que hacerlo manualmente.


Entity Framework 5 con .NET 4

Entity Framework 5 con .NET 4.5

Asi que simplemente hay que actualizar la referencia y hacer que apunte hacia la .dll que se encuentra en PackagesEntityFramework.5.0.0libnet45 o donde lo tengan:

Otros enlaces: