Метод расширения C # List to DataTable без получения свойств - PullRequest
0 голосов
/ 29 ноября 2018

Я хочу преобразовать ObservableCollection типа KNMOLijst в 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()
            {

            }
        }

Я убедился, что свойства были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();
        }
    }

Почему он не можетполучить свойства моего списка?

1 Ответ

0 голосов
/ 29 ноября 2018

Сгенерированный список является ObservableCollection<object>, поэтому я предполагаю, что если бы я добавил в него новую строку KNMOLijst, он имел бы тип KNMOLijst?

Нет, еслисписок имеет тип ObservableCollection<object>, тогда T равен System.Object, который не имеет открытых свойств.Так что сделайте это 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, который делает то же самое.Также нужно использовать отражение, чтобы получить столбцы.

...