C# List to DataTable 扩展方法不检索属性

C# List to DataTable extension method not retrieving properties

我想将 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;
        }
    }

下面的代码没有检索任何属性,我还尝试将非public成员包含在绑定标志中,但这对我来说似乎不起作用

//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()
            {

            }
        }

我确定属性是 public。

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

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();
        }
    }

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

The generatedlist is an ObservableCollection<object>, so I assume that if I would add a new KNMOLijst row into it, it would be of the type KNMOLijst?

不,如果列表是 ObservableCollection<object> 类型,则 TSystem.Object,它没有 public 属性。所以把它设为 ObservableCollection<KNMOLijst>.

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

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,后者的作用相同。它还需要使用反射来获取列。