none
Como mapear columnas dinamicas para el metodo listar C# .net? RRS feed

  • Pregunta

  • Estoy haciendo un método listar en C# .net pero al momento de mapear los campos existen también campos dinámicos que son las fechas que cambiarán de mes.

    Lo quiero es saber como manejar esas columnas al mapear dentro de mi objeto y además de ello como manejar varios campos ya que son todos los días del mes y tendría que agregarle 30 a 31 atributos a mi objeto para poder mapear 1 por 1 las fechas pero aun así estaría mal porque las columnas variarían.

    Este script es un store procedure que lista datos (idColaborador,NombreColaborador,IdUnidad_organizativa, y las fechas)  las fechas estan con pivot para que se invierta a columnas 

    ALTER PROCEDURE [dbo].[PA_Control_horas]
    @MesAño VARCHAR(6)--, --MesAño

    as
    begin
    DECLARE @SQLDynamic NVARCHAR(MAX)-- STRING QUE CONTENDRA TODO
    DECLARE @FinalDate NVARCHAR(50)=right(@MesAño,4)+'-'+'01-'+left(@MesAño,2)-- creamos el año + el mes + el primer dia

    --obtiene el primer dia del mes
    ;WITH CTE_DAY_Recursive AS
    (
    SELECT CAST(DATEADD(month, DATEDIFF(month, 0, @FinalDate), 0)  AS date)AS DayDINAMIC --Creamos el promer dia
    UNION ALL
    SELECT DATEADD(DAY,1,DayDINAMIC)--agregamos un dia mas
    FROM CTE_DAY_Recursive
    Where DATEADD(DAY,1,DayDINAMIC)<=CAST(DATEADD(MONTH,DATEDIFF(MONTH,0,@FinalDate)+1,0)-1 AS DATE)--verificamos que no se pase de la fecha del mes
    )
    SELECT  @SQLDynamic=COALESCE(@SQLDynamic+',','')+'['+CAST(DayDINAMIC    AS nvarchar(20))+']' 
    FROM CTE_DAY_Recursive  --Obtenemos los registros 

    DECLARE @SQLFULL NVARCHAR(MAX)='

    select * from
    (
    select 
        Id_Colaborador,
        Nombre_Colaborador,
        Id_Unidad_Organizativa,
        Fecha_Registro,
        sum(Hora_Registro) as ''Hora_Registro''
        from Sigeri
        group by Id_Colaborador,Nombre_Colaborador,Id_Unidad_Organizativa,Fecha_Registro
    )s
    pivot(
        max(Hora_Registro)
        for[Fecha_Registro] in --(select Fecha_Registro FROM Sigeri)
    ('+@SQLDynamic+') --Le pasamos los registros
    )p'


    EXEC(@SQLFULL)
    end

    Este método realiza el listado.

                        

    public List<Sigeri> ExportarResumenHoras()
                {
                    List<Sigeri> lista = new List<Sigeri>();
                    DatabaseHelper helper = null;
                    SqlDataReader dr = null;
                    try
                    {

                        helper = new DatabaseHelper(Conexion.Instancia.CadenaConexionDS());
                        //helper.AddParameter("@MesAño", "082019");
                        //dr = (DatabaseHelper)helper.ExecuteReader("PA_Control_Horas", System.Data.CommandType.StoredProcedure);

                        while (dr.Read())
                        {
                            var obj = new Sigeri()
                            {
                                Colaborador = new Colaborador()
                                {
                                    IdColaborador = dr["Id_Colaborador"].ToString(),
                                    NombreColaborador = dr["Nombre_Colaborador"].ToString()
                                },
                                Proyecto = new Proyecto()
                                {
                                    IdUnidadOrganizativa=dr["Id_Unidad_Organizativa"].ToString()
                                },
    //Fechas son dinámicas así que no le puedo asignar un nombre de atributo ya que el nombre de las columnas van a variar a menos que cree 30 atributos a mi objeto `SIGERI` pero aun asi variaría mi columna


                            };
                            lista.Add(obj);
                        }

                    }
                    catch (Exception ex)
                    {
                        throw ex;

                    }
                    finally
                    {
                        if (helper != null)
                            helper.Dispose();
                    }
                    return lista;

                }



    • Editado DUM28 miércoles, 2 de octubre de 2019 22:01
    miércoles, 2 de octubre de 2019 21:48

Todas las respuestas

  • Hola DUM28:

    Este es el foro de SQL Server y por la parte de este lenguaje, lo tienes cubierto. Te voy a exponer una posible variante a tú código, para quitar el cte recursivo y hacerlo más eficiente.

    CREATE PROCEDURE dbo.PA_Control_horas 
    (
    @MesAño Varchar(6)
    ) --,--MesAño
    AS
    BEGIN
    
    DECLARE @SQLDynamic NVARCHAR(MAX)= N'';-- STRING QUE CONTENDRA TODO
    DECLARE @FinalDate NVARCHAR(50)= RIGHT(@MesAño, 4) + '-' + '01-' + LEFT(@MesAño, 2);-- creamos el año + el mes + el primer dia
    DECLARE @HIGH INT= 31;
    DECLARE @LOW INT= 1;
    --obtiene el primer dia del mes
    DECLARE @FirstDay DATETIME=
    (
        SELECT CAST(DATEADD(month, DATEDIFF(month, 0, @FinalDate), 0) AS DATE)
    );
    --obtiene el primer dia del mes SIGUIENTE
    DECLARE @lastDay DATETIME= DATEADD(month, 1, @firstDay);
    WITH L0
         AS (SELECT c
             FROM(VALUES(1), (1), (1)) AS D(c)),
         L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
         L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
         Nums
         AS (SELECT ROW_NUMBER() OVER(
                    ORDER BY (SELECT NULL)) AS rownum
             FROM L2),
         Val
         AS (SELECT TOP (@high - @low + 1) @low + rownum - 1 AS n
             FROM Nums
             ORDER BY rownum)
         SELECT @SQLDynamic = CONCAT(@SQLDynamic , QUOTENAME(CAST(DATEADD(DAY, Val.n - 1, @FirstDay) AS DATE)),',')
    	   FROM VAL
    		  WHERE @lastDay > DATEADD(DAY, Val.n - 1, @FirstDay)
    
    SELECT @SQLDynamic=SUBSTRING(@SQLDynamic,1,LEN(@SQLDYNAMIC)-1);/* eliminamos la ultima coma */
    
    DECLARE @SQLFULL NVARCHAR(MAX)='
    
    select * from
    (
    select 
        Id_Colaborador,
        Nombre_Colaborador,
        Id_Unidad_Organizativa,
        Fecha_Registro,
        sum(Hora_Registro) as ''Hora_Registro''
        from Sigeri
        group by Id_Colaborador,Nombre_Colaborador,Id_Unidad_Organizativa,Fecha_Registro
    )s
    pivot(
        max(Hora_Registro)
        for[Fecha_Registro] in --(select Fecha_Registro FROM Sigeri)
    ('+@SQLDynamic+') --Le pasamos los registros
    )p'
    
    
    EXEC(@SQLFULL)
    
    END

    En cuanto al resto de tu pregunta, creo que debes de trasladarla al foro de MSDN para c#

    Foro c#

    jueves, 3 de octubre de 2019 4:05