简体   繁体   English

C#列表到DataTable扩展方法未检索属性

[英]C# List to DataTable extension method not retrieving properties

I want to convert a ObservableCollection of type KNMOLijst to a DataTable. 我想将KNMOLijst类型的ObservableCollection转换为DataTable。 I found a extension method for it, but it is not retrieving my properties? 我找到了扩展方法,但是它没有检索我的属性?

Extension method: 扩展方式:

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

The peace of code below is not retrieving any properties, I also tried to include the nonpublic members in the bindingflags, but that didn't seem to work for me 下面代码的安全性没有检索任何属性,我还尝试将非公共成员包括在bindingflags中,但这似乎对我不起作用

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

This is the type KNMOLijst it receives: 这是它收到的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()
            {

            }
        }

I made sure that the properties were public. 我确保这些属性是公开的。

This is the list that the extension method receives. 这是扩展方法接收的列表。

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"]
                });

My viewmodel that invokes the ToDataTable method. 我的视图模型调用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();
        }
    }

Why is it not able to get the properties of my list? 为什么无法获取列表的属性?

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? GeneratedList是一个ObservableCollection<object> ,因此我假设如果要向其中添加新的KNMOLijst行,它将是KNMOLijst类型吗?

No, if the list is of type ObservableCollection<object> then T is System.Object which has no public properties. 否,如果列表的类型为ObservableCollection<object>TSystem.Object ,它没有公共属性。 So make it a ObservableCollection<KNMOLijst> . 因此,使其成为ObservableCollection<KNMOLijst>

If you can't do that modify the method to derive the type from the first item: 如果您不能这样做,请修改方法以从第一项派生类型:

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

    // ...
}

By the way, this behavior(throwing InvalidOperationException on empty list) is similar to CopyToDataTable which does the same. 顺便说一句,此行为(将InvalidOperationException扔到空列表上)与CopyToDataTable相似。 It also needs to use reflection to get the columns. 它还需要使用反射来获取列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM