【问题标题】:C# List to DataTable extension method not retrieving propertiesC# List to DataTable 扩展方法不检索属性
【发布时间】:2018-11-29 15:01:23
【问题描述】:

我想将 KNMOLijst 类型的 ObservableCollection 转换为 DataTable。我找到了它的扩展方法,但它没有检索我的属性?

扩展方法:

public static class ListToDataTable
    {
        public static DataTable ToDataTable<T>(this IList<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)
            {
                //Defining type of data column gives proper data table 
                var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
                //Setting column names as Property names
                dataTable.Columns.Add(prop.Name, type);
            }
            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
                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }
            //put a breakpoint here and check datatable
            return dataTable;
        }
    }

下面的代码和平没有检索任何属性,我也尝试在绑定标志中包含非公共成员,但这似乎对我不起作用

//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

这是它接收的 KNMOLijst 类型:

   public class KNMOLijst
        {
            public string VoorLetters { get; set; }

            public string Voornaam { get; set; }

            public string TussenVoegsel { get; set; }

            public string Achternaam { get; set; }

            public string Geslacht { get; set; }

            public DateTime GeboorteDatum { get; set; }

            public string InstrumentNaam { get; set; }

            public KNMOLijst()
            {

            }
        }

我确保这些属性是公开的。

这是扩展方法接收的列表。

generatedList.Add(new KNMOLijst()
                {
                    VoorLetters = (string)(row["VoorLetters"]),
                    Voornaam = (string)(row["Voornaam"]),
                    TussenVoegsel = (string)(row["TussenVoegsel"]),
                    Achternaam = (string)row["Achternaam"],
                    Geslacht = (string)row["Geslacht"],
                    GeboorteDatum = (DateTime)row["GeboorteDatum"],
                    InstrumentNaam = (string)row["InstrumentNaam"]
                });

调用 ToDataTable 方法的视图模型。

public class SecretarisViewModel : BaseViewModel
    {
        private readonly SecretarisBLL secretarisBll;

        private ObservableCollection<object> generatedList;

        public ObservableCollection<object> GeneratedList
        {
            get { return generatedList; }
            set
            {
                generatedList = value;
                NotifyPropertyChanged();
            }
        }

        private DataTable generatiedDataTable;

        public DataTable GeneratedDataTable
        {
            get => generatiedDataTable;
            set
            {
                generatiedDataTable = value;
                NotifyPropertyChanged();
            }
        }

        public SecretarisViewModel()
        {
            secretarisBll = new SecretarisBLL();
            GeneratedList = new ObservableCollection<object>();
            generatiedDataTable = new DataTable();
        }

        public async Task GetKNMOList()
        {
            var dataset = await secretarisBll.GetKNMOList();

            foreach (DataRow row in dataset.Tables[0].Rows)
            {
                generatedList.Add(new KNMOLijst()
                {
                    VoorLetters = (string)(row["VoorLetters"]),
                    Voornaam = (string)(row["Voornaam"]),
                    TussenVoegsel = (string)(row["TussenVoegsel"]),
                    Achternaam = (string)row["Achternaam"],
                    Geslacht = (string)row["Geslacht"],
                    GeboorteDatum = (DateTime)row["GeboorteDatum"],
                    InstrumentNaam = (string)row["InstrumentNaam"]
                });
            }

            GeneratedDataTable = generatedList.ToDataTable();
        }
    }

为什么无法获取我列表的属性?

【问题讨论】:

  • T 是什么——generatedList 的类型是什么?如果它不是实现IList&lt;KNMOLijst&gt; 的东西,它就行不通。
  • 到目前为止您尝试过什么? List 的类型是否正确?该代码对我有用。
  • 检查了您的样品并且工作正常。所以我猜你的row 不包含这些值。
  • 可以在调用 ToDataTable 方法的地方添加代码吗?
  • @JeroenMostert 生成的列表是一个 ObservableCollection,所以我假设如果我要在其中添加一个新的 KNMOLijst 行,它将是 KNMOLijst 类型?

标签: c# .net generics reflection extension-methods


【解决方案1】:

生成的列表是ObservableCollection&lt;object&gt;, 所以我假设如果我要在其中添加一个新的 KNMOLijst 行,它会 是 KNMOLijst 类型吗?

不,如果列表是ObservableCollection&lt;object&gt; 类型,那么TSystem.Object,它没有公共属性。所以让它成为ObservableCollection&lt;KNMOLijst&gt;

如果您不能这样做,请修改方法以从第一项派生类型:

public static DataTable ToDataTable<T>(this IList<T> items)
{
    Type type = items.FirstOrDefault()?.GetType();
    if (type == null)
        throw new InvalidOperationException("The properties are derived from the first item, so the list must not be empty");

    DataTable dataTable = new DataTable(type.Name);
    //Get all the properties
    PropertyInfo[] Props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

    // ...
}

顺便说一句,这种行为(在空列表中抛出InvalidOperationException)类似于CopyToDataTable,它的作用相同。它还需要使用反射来获取列。

【讨论】:

  • 我试过这个,但在调试时它跳过了类型检查。这是到达该行时包含的类型:{Name = "KNMOLijst" FullName = "Gildenbondsharmonie.BO.Lists.KNMOLijst"}。但它仍然没有收到我的属性?
  • @Brum: 跳过了哪种类型检查?
  • 那部分:Type type = items.FirstOrDefault()?.GetType(); if (type == null) type = typeof(T);但我将附上项目中内容的屏幕截图。
  • @Brum:我已经用您的样本检查了该方法并将其声明为ObservableCollection&lt;Object&gt;。在我的更改之前它不起作用,因为 System.Object 被用作类型,现在它起作用了。
  • 你我的男人,是我的英雄!我没有注意到你有一次机会,当我改变我的代码时它起作用了。谢谢你的时间我真的很感激!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 2021-12-23
  • 1970-01-01
  • 2018-01-15
相关资源
最近更新 更多