miércoles, 31 de mayo de 2017

113. Redist Cache 01

Las bases de datos han evolucionado, así como la información también ha crecido, la producción de información hoy en día es varias veces superior a la información que se producía hace 10 años.

La información es un tesoro, y es muy importante poder analizarlo de forma adecuada, el análisis es una tarea compleja, ya que acceder a la información estructurada puede ser muy costoso, además existe el hecho de que la información que se encuentra en la naturaleza no se encuentra estructurado.

La información en la naturaleza puede ser variable, e interpretarla puede ser complejo, es ahí cuando entran las bases de datos no estructuradas o noSQL, dichas bases nos permiten manipular datos sin que estos tengan una estructura como tal.

Se tiene un universo muy amplio de este tipo de bases de datos, y de la base que vamos ha hablar es una base de este universo, esta base es llamada Redist Cache, esta es una base de datos creada en C, que además de ser no SQL tiene una característica muy importante, es extremadamente rápida.

Cuando se habla de un alto procesamiento de datos los milisegundos cuentan, ya que estos al juntarse se convierten en segundos, minutos, horas o días.

La rapidez de esta base de datos se debe principalmente a su estructura, se encuentra estructurada como un gran diccionario de datos, y a que la base de datos se encuentra en la memoria.

Al ser una base de datos de estas características su velocidad es muy alta, hoy en día, el costo del hardware se abarata, y como consecuencia es fácil tener una base de datos in-memory.

Esta base de datos, se creo en el sistema Linux, posteriormente se migro una versión a Windows, pero la magia de ella no se encuentra ahí, la magia de ella se encuentra en la posibilidad de poderla contratar como un servicio server less en la nube, de esta forma se obtiene una base de datos muy rápida, para procesar, grandes cantidades de información, que se puede almacenar en una infraestructura a la medida, en la que se paga solo por lo que se ocupa.



Felices lineas

viernes, 26 de mayo de 2017

112. Lynq Group by con multiples columnas

Lynq es una herramienta muy poderosa ya que nos permite manejar y manipular datos de una manera muy sencilla, es importante que todo desarrollador de C# la maneje de la manera correcta, en esta ayuda rápida, vamos a mostrar como agrupar una lista con mas de una columna.

En este caso es de gran ayuda un método anónimo, con el crearemos la estructura que entenderá Groupby para poder efectuar la agrupación.

Detalle.GroupBy(s => new { s.Impuesto, s.Factor, s.Tasa });

considerando que detalle es un tipo de datos complejo en un generic.


Felices líneas

111. Obtener los tributos duplicados de una lista

Un caso muy especial en las listas, es que muchas veces deseamos buscar los elementos duplicados, a que me refiero.

Supongamos que tenemos la siguiente lista

1,5,6,7,7,8,9

Yo esperaría obtener los números duplicados, es decir  7

¿Cómo lo hago?

Es muy fácil por medio de lynq

List<String> duplicados = Impuesto.GroupBy(s => s).SelectMany(grp => grp.Skip(1)).ToList();

Agrupamos la lista que deseamos validar, y le pedimos que se salte aquellos en los que solo encuentre 1

Felices Líneas


110. Unir archivos XSD

El esquema de un XML, nos da el formato del mismo, nos ayuda por que de esta forma tenemos el XML definido, sabemos que campos puede contener, de que tipo serán estos y en que lugar se deben encontrar estos.

Una ventaja de los archivos de formato XSD es que el esquema puede encontrarse definido en mas de un archivo, esto nos permite comprender el XML y separarlo en cada una de sus partes, pero una gran desventaja es que durante la validación es necesario unir el archivo en un solo XSD, eliminando todos aquellos atributos, tipos de datos o nodos duplicados

Una forma de eliminar estas entidades es por medio de la siguiente función:


//La función recibe un XMLSchemaSet que ya se encuentra cargado y un esquema que en ese momento se encuentra en disco
public XmlSchemaSet MergeSchemas(XmlSchemaSet schemaSet1, string schema2)
{
//Es necesario compilar el esquema para poderlo emplear y para validar que este es un esquema valido
     schemaSet1.Compile();
//Leemos el segundo esquema y lo compilamos
     XmlSchemaSet schemaSet2 = new XmlSchemaSet();
     schemaSet2.Add(null, schema2);
     schemaSet2.Compile();

//Se deben efectuar 3 validaciones por las variables que se encuentran en el XSD y se deben eliminar los elementos duplicados, es importante mencionar que se quitan los elementos duplicados pero este proceso no tiene la inteligencia para determinar cual de los 2 elementos tiene la ultima versión del mismo, este método se hace considerando que ambos elementos son iguales y que se busca que solo uno de ellos se conserve para que durante la validación de esquema no se genere un error de validación por un elemento duplicado. También es importante considerar que los tipos de dato se agreguen al XSD por medio de un import para que los XSD se encuentren completos al momento de compilarlos.

foreach (XmlSchemaElement el1 in schemaSet1.GlobalElements.Values)
{
     foreach (XmlSchemaElement el2 in schemaSet2.GlobalElements.Values)
     {
          if (el2.QualifiedName.Equals(el1.QualifiedName))
          {
               ((XmlSchema)el2.Parent).Items.Remove(el2);
               break;
           }
      }
}

foreach (XmlSchemaAttribute el1 in schemaSet1.GlobalAttributes.Values)
{
       foreach (XmlSchemaAttribute el2 in schemaSet2.GlobalAttributes.Values)
       {
             if (el2.QualifiedName.Equals(el1.QualifiedName))
             {
                   ((XmlSchema)el2.Parent).Items.Remove(el2);
                   break;
              }
       }
}
//Es muy importante que en este caso el valor se guarde en un tipo objeto, por que se pueden recibir diversos tipos de datos y estos deben ser analizados
foreach (Object el1 in schemaSet1.GlobalTypes.Values)
{
     foreach (Object el2 in schemaSet2.GlobalTypes.Values)
     {
          if (el1.GetType() == typeof(XmlSchemaSimpleType))
          {                      
                XmlSchemaSimpleType elt1 = (XmlSchemaSimpleType)el1;
                if (el2.GetType() == typeof(XmlSchemaSimpleType))
                {
                      XmlSchemaSimpleType elt2 = (XmlSchemaSimpleType)el2;
                      if (elt2.QualifiedName.Equals(elt1.QualifiedName))
                      {
                           ((XmlSchema)elt2.Parent).Items.Remove(elt2);
                           break;
                       }
                  }
             }
            
             if (el1.GetType() == typeof(XmlSchemaComplexType))
            {
                  XmlSchemaComplexType elt1 = (XmlSchemaComplexType)el1;
                  if (el2.GetType() == typeof(XmlSchemaComplexType))
                  {
                        XmlSchemaComplexType elt2 = (XmlSchemaComplexType)el2;
                        if (elt2.QualifiedName.Equals(elt1.QualifiedName))
                        {
                             if ((XmlSchema)elt2.Parent != null)
                            {
                                  ((XmlSchema)elt2.Parent).Items.Remove(elt2);
                                    break;
                            }
                       }
                  }
             }
        }
   }
  
   foreach (XmlSchema schema in schemaSet2.Schemas())
   {
        schemaSet2.Reprocess(schema);
   }
           
   schemaSet1.Add(schemaSet2);
   schemaSet1.Compile();
  
   return schemaSet1;
}

Felices Lineas!!!!

miércoles, 24 de mayo de 2017

109. Firmar con rsa - SHA256 C# - certificado del almacen de windows

Antes que nada, debo aclarar que la firma de una cadena se efectúa por medio de la clave privada, por lo que deben verificar que la clave privada se encuentren dentro del almacén para posteriormente hacer la firma de la cadena.

Veamos el código y expliquemoslo

//Establecemos el numero de certificado, que se empleara para la firma, dicho certificado deberá estar dentro del almacen de certificados de Windows y deberá tener su clave privada
 string noSerie = "3030323031303030303030313030303030383133";
//Establecemos la cadena que se firmara
 string CadenaAFirmar = "holaMundo";
//Buscamos el certificado que se empleara para la firma dentro del almacén de certificados
 X509Store almacen = null;
 almacen = new X509Store(StoreLocation.LocalMachine);
 almacen.Open(OpenFlags.OpenExistingOnly);
 X509Certificate2Collection Certificados = almacen.Certificates.Find(X509FindType.FindBySerialNumber, noSerie, false);
 X509Certificate2 CertificadoFirma = Certificados[0];
 almacen.Close();

//Se carga la clave privada
RSACryptoServiceProvider csp = null;
csp = (RSACryptoServiceProvider)CertificadoFirma.PrivateKey;
var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo;
var cspparametro = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, csp.CspKeyContainerInfo.KeyContainerName);
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspparametro))
            {
//Se firma la cadena
                rsa.PersistKeyInCsp = true;
                byte[] bytefirma = rsa.SignData(Encoding.UTF8.GetBytes(CadenaAFirmar), "SHA256");
                return bytefirma;
            }

Felices lineas

martes, 23 de mayo de 2017

108. XDocument consulta rapida

XDocument nos presenta una forma rápida de consultar un XML, es mas rápido que un XMLDocument dado que este guarda toda la información en memoria, XMLDocument, permite la carga de documentos de gran tamaño, dado que guarda únicamente un puntero al documento, XML document trae un conjunto de funciones útiles, dado que es un objeto mas grande, una de ellas es la posibilidad de dar una ruta para que se encuentre un nodo en particular, esto no lo podemos hacer con XDocument, ya que debemos ir nodo a nodo para hacer el análisis.

La siguiente función busca emular esta característica de XMLDocument, para poder aprovechar las ventajas en velocidad que nos da XDocument.

       public string ObtenerAtributo(XDocument Documento, string rutaAtributos, string RutasEspacoNombres)
        {
            EspaciosDeNombres objEspaciosNombres = new EspaciosDeNombres();
            List<EspacioDeNombres> EspaciosDeNombres = objEspaciosNombres.CargarEspaciosDeNombres(RutasEspacoNombres);
            String[] rAtributos = rutaAtributos.Split('\\');
            int AtributoUbicacion = rAtributos.Count() - 1;

            int contador = 0;
            XElement objElement = null;
            while (contador < AtributoUbicacion)
            {
                string[] AtributosComponentes = rAtributos[contador].Split(':');
                XNamespace EsNombres = EspaciosDeNombres.Find(c => AtributosComponentes[0] == c.Nombre).EspacioNombres;
                if (contador == 0)
                {
                    objElement = Documento?.Element(EsNombres + AtributosComponentes[1]);
                }
                else
                {
                    objElement = objElement?.Element(EsNombres + AtributosComponentes[1]);
                }
                contador++;
            }
            //Obteniendo el atributo
            return objElement?.Attribute(rAtributos[AtributoUbicacion])?.Value;
        }


¿Qué hace el código?

Recorre todas las rutas del XML con el fin de buscar el atributo especificado, dando una cadena en la que se establezca la ruta de un atributo.


Felices Lineas