【问题标题】:Convert List to datatable, having some properties also as List将列表转换为数据表,具有一些属性也作为列表
【发布时间】:2020-06-07 16:29:59
【问题描述】:

我需要从 DetelleHora 类型的对象列表创建一个 DataTable。 This post explains how to accomplish it,为 DetalleHora 的每个属性创建一列。

我面临的问题是 DetalleHora 的属性之一是 Hora 类型的对象列表,将包含未定义数量的项目(这就是为什么我不能这样做this),并且我无法遍历此列表,以便生成的 DataTable 包含每个项目的列。

这是 DetalleHora 类定义:

class DetalleHora
{
    public int Id { get; set; }
    public string Fecha { get; set; }
    public string Solicitante { get; set; }
    public string Orden { get; set; }
    public string DMR { get; set; }
    public string Descripcion { get; set; }
    public string Operario { get; set; }
    public string Entrada { get; set; }
    public string Salida { get; set; }
    public List<Hora> Horas { get; set; }
    public double TotalHoras { get; set; }
    public string FirmaSolicitante { get; set; }
    public int NumeroSemana { get; set; }
}

这是 Hora 类定义:

public class Hora
{
    public int IdTipoHora { get; set; }
    public string Tipo { get; set; }
    public double Cantidad { get; set; }
}

这就是我正在做的事情(根据以下链接之一):

public DataTable ListToDataTable<T>(List<T> items)
    {
        DataTable dataTable = new DataTable(typeof(T).Name);

        //Get all the properties
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo prop in Props)
        {
            //Setting column names as Property names
            // ******* I need a new column for each item in the List<Hora> Property
            dataTable.Columns.Add(prop.Name);
        }
        foreach (T item in items)
        {
            var values = new object[Props.Length];
            for (int i = 0; i < Props.Length; i++)
            {
                //inserting property values to datatable rows
                // *********** BUT THIS WON'T WORK WHEN PROPERTY IS A LIST<T>
                // I need a new column for each of the items in the List<Hora> Property
                values[i] = Props[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }
        //put a breakpoint here and check datatable
        return dataTable;
    }

我正在寻找一种方法来确定给定属性是否是特定类型对象的列表,但以下方法似乎都不适合我:

【问题讨论】:

  • 如果prop 是一个集合,如何为List&lt;Hora&gt; Horas 创建新的DataTable 并将数据添加到此数据表中。
  • 问题是我无法确定prop是否是一个集合:(
  • 是的,你可以点赞:if ((Props[i].GetValue(item, null) is IList list)) {//use list here},你也可以在这里ListToDataTable recurisvely 在另一个里面构建dataTable。第二种解决方案:像 array 一样声明 Horas 并使用 Props[i].PropertyType.IsArray

标签: c# list datatable


【解决方案1】:

尝试关注

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Fecha", typeof(string));
            dt.Columns.Add("Solicitante", typeof(string));
            dt.Columns.Add("Orden", typeof(string));
            dt.Columns.Add("DMR", typeof(string));
            dt.Columns.Add("Description", typeof(string));
            dt.Columns.Add("Operario", typeof(string));
            dt.Columns.Add("Entrada", typeof(string));
            dt.Columns.Add("Salida", typeof(string));
            dt.Columns.Add("IdTipoHora", typeof(int));
            dt.Columns.Add("Tipo", typeof(string));
            dt.Columns.Add("Cantidad", typeof(string));
            dt.Columns.Add("TotalHoras", typeof(double));
            dt.Columns.Add("FirmSolicitante", typeof(string));
            dt.Columns.Add("NumeroSemana", typeof(int));

            List<DetalleHora> detailHoras = new List<DetalleHora>();

            foreach (DetalleHora detailHora in detailHoras)
            {
                foreach (Hora hora in detailHora.Horas)
                {
                    dt.Rows.Add(new object[] {
                        detailHora.Id,
                        detailHora.Fecha,
                        detailHora.Solicitante,
                        detailHora.Orden,
                        detailHora.DMR,
                        detailHora.Description,
                        detailHora.Operario,
                        detailHora.Entrada,
                        detailHora.Salida,
                        hora.IdTipoHora,
                        hora.Tipo,
                        hora.Cantidad,
                        detailHora.TotalHoras,
                        detailHora.FirmaSolicitante,
                        detailHora.NumeroSemana
                    });
                }
            }

        }
    }
    class DetalleHora
    {
        public int Id { get; set; }
        public string Fecha { get; set; }
        public string Solicitante { get; set; }
        public string Orden { get; set; }
        public string DMR { get; set; }
        public string Description { get; set; }
        public string Operario { get; set; }
        public string Entrada { get; set; }
        public string Salida { get; set; }
        public List<Hora> Horas { get; set; }
        public double TotalHoras { get; set; }
        public string FirmaSolicitante { get; set; }
        public int NumeroSemana { get; set; }
    }
    public class Hora
    {
        public int IdTipoHora { get; set; }
        public string Tipo { get; set; }
        public double Cantidad { get; set; }
    }
}

【讨论】:

  • 恐怕这行不通。我需要为 List Horas 中的每个项目在数据表中添加一列。我的意思是,Horas 最多可以包含 120 个不同的项目,我需要为每个项目创建一个列。谢谢。
  • 我已经这样做了。为了使数据有意义,您需要对每个 hora 行重复 DetailHora 行。
【解决方案2】:

我想将 List&lt;DetalleHora&gt; 转换为 DataTable,以便使用它以优雅高效的方式使用 NPOI 库生成 Excel 文件。

但是,因为赶时间,我放弃了最初的想法,决定编写 Excel 文件循环遍历 Lists 的项目。

还是谢谢。

【讨论】:

    猜你喜欢
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    相关资源
    最近更新 更多