03 junio 2025

C# DataAnnotations

/// <summary>
/// Token class
/// </summary>
[Index(nameof(AccessToken), IsUnique = true, Name = "Uk_DataModel_AccessToken")]
[Index(nameof(Status), Name = "Ix_DataModel_Status")]
[Index("Descripcion", Name = "UK_DataModel_Descripcion", IsUnique = true)]
public class DataModel
{
    /// <summary>
    /// Defgult constructor
    /// </summary>
    public DataModel()
    {
        UsernameChangeLimit = 10;
        Id = Guid.NewGuid();
        CreatedDate = DateTimeOffset.UtcNow.AddHours(-5);
        Status = Status.Active;
        ProfilePicture = Convert.FromBase64String("iVBORw0KGgo...");
    }

    /// <summary>
    /// Expire Minutes property
    /// </summary>
    [Required]
    [Range(1, 1440)]
    public int ExpireMinutes { get; set; }

    /// <summary>
    /// Symmetric Security Key property
    /// </summary>
    [Required]
    [ProtectedPersonalData]
    public string SymmetricSecurityKey { get; set; }

    /// <summary>
    /// Id property
    /// </summary>
    [Key]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    /// <summary>
    /// Profile Picture
    /// </summary>
    [Comment("ProfilePicture")]
    [Display(Name = "Imagen usuario")]
    [Required(ErrorMessage = "{0} requerido")]
    public byte[] ProfilePicture { get; set; }

    /// <summary>
    /// First Name
    /// </summary>
    [PersonalData]
    [Comment("Nombre")]
    [Display(Name = "Nombre")]
    [Required(ErrorMessage = "{0} requerido")]
    [StringLength(50)]
    [MinLength(3, ErrorMessage = "{0} mínimo {1} caracteres")]
    [MaxLength(50, ErrorMessage = "{0} máximo {1} caracteres")]
    public string FirstName { get; set; }

    /// <summary>
    /// Username Change Limit
    /// </summary>
    [Comment("UsernameChangeLimit")]
    [Display(Name = "Límite cambio usuario")]
    [Range(1, 20, ErrorMessage = "{0} rango entre {1} y {2}")]
    public int UsernameChangeLimit { get; set; }

    /// <summary>
    /// Created Date property
    /// </summary>
    [Comment("CreatedDate")]
    [Display(Name = "Fecha creación")]
    [Required(ErrorMessage = "{0} requerido")]
    [DataType(DataType.DateTime, ErrorMessage = "{0} formato fecha incorrecto")]
    public DateTimeOffset CreatedDate { get; set; }

    /// <summary>
    /// Descripcion
    /// </summary>
    public string Descripcion { get; set; }

    [Comment("Price")]
    [Display(Name = "Precio")]
    [Range(0.1, 999999999, ErrorMessage = "{0} rango entre {1} y {2}")]
    public decimal Precio { get; set; }
}

C# Enum description

using System.ComponentModel;
using System.Reflection;

#nullable disable

namespace Tools.Domain.Helpers;

/// <summary>
/// Proporciona métodos auxiliares para trabajar con enumeradores.
/// </summary>
public static class EnumHelper
{
    /// <summary>
    /// Obtiene la descripción asociada a un valor de enumerador utilizando el atributo <see cref="DescriptionAttribute"/>.
    /// Si no se encuentra el atributo <see cref="DescriptionAttribute"/>, devuelve el nombre del valor del enumerador.
    /// </summary>
    /// <param name="value">El valor del enumerador del cual se desea obtener la descripción.</param>
    /// <returns>
    /// La descripción del valor del enumerador si existe el atributo <see cref="DescriptionAttribute"/>;
    /// de lo contrario, el nombre del valor del enumerador.
    /// </returns>
    /// <example>
    /// Ejemplo de uso:
    /// <code>
    /// public enum Status
    /// {
    ///     [Description("Activo")]
    ///     Active = 1,
    ///     [Description("Inactivo")]
    ///     Inactive = 2,
    ///     [Description("Eliminado")]
    ///     Deleted = 3
    /// }
    ///
    /// Console.WriteLine(EnumHelper.GetDescription(Status.Active)); // Salida: "Activo"
    /// </code>
    /// </example>
    public static string GetDescription(Enum value)
    {
        FieldInfo field = value.GetType().GetField(value.ToString());
        DescriptionAttribute attribute = field.GetCustomAttribute<DescriptionAttribute>();

        if (attribute == null) { return value.ToString(); }

        return attribute?.Description ?? value.ToString();
    }
}

/// <summary>
/// Representa los estados de un elemento en el sistema.
/// </summary>
public enum Status
{
    /// <summary>
    /// Estado Activo.
    /// Indica que el elemento está disponible y en uso.
    /// </summary>
    [Description("Activo")]
    Active = 1,

    /// <summary>
    /// Estado Inactivo.
    /// Indica que el elemento no está disponible temporalmente.
    /// </summary>
    [Description("Inactivo")]
    Inactive = 2,

    /// <summary>
    /// Estado Eliminado.
    /// Indica que el elemento ha sido marcado como eliminado
    /// y no debe mostrarse en las operaciones normales del sistema.
    /// </summary>
    [Description("Eliminado")]
    Deleted = 3
}

HTML Plantilla favicon base64

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Página de inicio del proyecto" />
    <meta name="keywords" content="inicio, proyecto, ejemplo" />
    <meta name="author" content="Proyecto Global" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Página de Inicio</title>
    <!-- Favicon -->
    <link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEp
IrGAAAAn1BMVEUAAADCAAAAAAA3yDfUAAA3yDfUAAA8PDzr6+sAAAD4+Pg3yDeQkJDTAADt7e3V1dU3
yDdCQkIAAADbMTHUAABBykHUAAA2yDY3yDfr6+vTAAB3diDR0dGYcHDUAAAjhiPSAAA3yDeuAADUAAA
3yDf////OCALg9+BLzktBuzRelimzKgv87+/dNTVflSn1/PWz6rO126g5yDlYniy0KgwjJ0TyAAAAI3
RSTlMABAj0WD6rJcsN7X1HzMqUJyYW+/X08+bltqSeaVRBOy0cE+citBEAAADBSURBVDjLlczXEoIwF
IThJPYGiL0XiL3r+z+bBOJs9JDMuLffP8v+Gxfc6aIyDQVjQcnqnvRDEQwLJYtXpZT+YhDHKIjLbS+O
UeT4TjkKi6OwOArq+yeKXD9uDqQQbcOjyCy0e6bTojZSftX+U6zUQ7OuittDu1k0WHqRFfdXQijgjKf
F6ZwAikvmKD6OQjmKWUcDigkztm5FZN05nMON9ZcoinlBmTNnAUdBnRbUUbgdBZwWbkcBpwXcVsBtxf
jb31j1QB5qeebOAAAAAElFTkSuQmCC" rel="icon" type="image/x-icon" />
  </head>
  <body></body>
</html>

18 mayo 2025

MS SQL Server - Cursor Index AVG Fragmentation in Percent

DECLARE @MyTableVar TABLE ([schema_name] nvarchar(256),[object_name] nvarchar(256),index_name nvarchar(256),index_type nvarchar(120), avg_fragmentation_in_percent float(8),page_count bigint,alloc_unit_type_desc nvarchar(120));

 

DECLARE @Reg VARCHAR(255);

DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR SELECT [name] FROM sys.tables;

OPEN MY_CURSOR;

FETCH NEXT FROM MY_CURSOR INTO @Reg;

WHILE @@FETCH_STATUS = 0

BEGIN

INSERT INTO @MyTableVar SELECT OBJECT_SCHEMA_NAME(ips.object_id) AS schema_name, OBJECT_NAME(ips.object_id) AS object_name, i.name AS index_name, i.type_desc AS index_type, ips.avg_fragmentation_in_percent, ips.page_count, ips.alloc_unit_type_desc FROM sys.dm_db_index_physical_stats(DB_ID(), (SELECT st.object_id FROM SYS.tables st WHERE st.[name] = @Reg), default, default, 'LIMITED') AS ips INNER JOIN sys.indexes AS i ON ips.object_id = i.object_id AND ips.index_id = i.index_id ORDER BY page_count DESC;

FETCH NEXT FROM MY_CURSOR INTO @Reg;

END

CLOSE MY_CURSOR;

DEALLOCATE MY_CURSOR;

SELECT * FROM @MyTableVar WHERE index_type NOT IN ('HEAP') AND object_name NOT IN ('sysdiagrams') AND avg_fragmentation_in_percent > 0 ORDER BY 2;

GO