Using Reflection to create a DataTable from a Class?

后端 未结 9 1968
星月不相逢
星月不相逢 2020-12-02 07:39

I\'ve just learned about Generics and I\'m wondering whether I can use it to dynamically build datatables from my classes.

Or I might be missing the point here. Here

相关标签:
9条回答
  • 2020-12-02 08:18

    The error can be resolved by changing this:

    dogTable = CreateDataTable(Dog);
    

    to this:

    dogTable = CreateDataTable(typeof(Dog));
    

    But there are some caveats with what you're trying to do. First, a DataTable can't store complex types, so if Dog has an instance of Cat on it, you won't be able to add that as a column. It's up to you what you want to do in that case, but keep it in mind.

    Second, I would recommend that the only time you use a DataTable is when you're building code that knows nothing about the data its consuming. There are valid use cases for this (e.g. a user-driven data mining tool). If you already have the data in the Dog instance, just use it.

    Another little tidbit, this:

    DataTable dogTable = new DataTable();
    dogTable = CreateDataTable(Dog);
    

    can be condensed to this:

    DataTable dogTable = CreateDataTable(Dog);
    
    0 讨论(0)
  • 2020-12-02 08:24

    you can convert the object to xml then load the xml document to a dataset, then extract the first table out of the data set. However i dont see how this be practical as it infers creating streams, datasets & datatables and using converstions to create the xml document.

    I guess for proof of concept i can understand why. Here is an example, but somewhat hesitant to use it.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Data;
    using System.Xml.Serialization;
    
    namespace Generics
    {
    public class Dog
    {
        public string Breed { get; set; }
        public string Name { get; set; }
        public int legs { get; set; }
        public bool tail { get; set; }
    }
    
    class Program
    {
        public static DataTable CreateDataTable(Object[] arr)
        {
            XmlSerializer serializer = new XmlSerializer(arr.GetType());
            System.IO.StringWriter sw = new System.IO.StringWriter();
            serializer.Serialize(sw, arr);
            System.Data.DataSet ds = new System.Data.DataSet();
            System.Data.DataTable dt = new System.Data.DataTable();
            System.IO.StringReader reader = new System.IO.StringReader(sw.ToString());
    
            ds.ReadXml(reader);
            return ds.Tables[0];
        }
    
        static void Main(string[] args)
        {
            Dog Killer = new Dog();
            Killer.Breed = "Maltese Poodle";
            Killer.legs = 3;
            Killer.tail = false;
            Killer.Name = "Killer";
    
            Dog [] array_dog = new Dog[5];
            Dog [0] = killer;
            Dog [1] = killer;
            Dog [2] = killer;
            Dog [3] = killer;
            Dog [4] = killer;
    
            DataTable dogTable = new DataTable();
            dogTable = CreateDataTable(array_dog);
    
            // continue here
    
            }      
        }
    }
    

    look the following example here

    0 讨论(0)
  • 2020-12-02 08:24

    If you want to set columns order/ Include only some columns/ exclude some columns try this:

            private static DataTable ConvertToDataTable<T>(IList<T> data, string[] fieldsToInclude = null,
    string[] fieldsToExclude = null)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
            {
                if ((fieldsToInclude != null && !fieldsToInclude.Contains(prop.Name)) ||
                    (fieldsToExclude != null && fieldsToExclude.Contains(prop.Name)))
                    continue;
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            }
    
            foreach (T item in data)
            {
                var atLeastOnePropertyExists = false;
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                {
    
                    if ((fieldsToInclude != null && !fieldsToInclude.Contains(prop.Name)) ||
    (fieldsToExclude != null && fieldsToExclude.Contains(prop.Name)))
                        continue;
    
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                    atLeastOnePropertyExists = true;
                }
    
                if(atLeastOnePropertyExists) table.Rows.Add(row);
            }
    
    
            if (fieldsToInclude != null)
                SetColumnsOrder(table, fieldsToInclude);
    
            return table;
    
        }
    
        private static void SetColumnsOrder(DataTable table, params String[] columnNames)
        {
            int columnIndex = 0;
            foreach (var columnName in columnNames)
            {
                table.Columns[columnName].SetOrdinal(columnIndex);
                columnIndex++;
            }
        }
    
    0 讨论(0)
提交回复
热议问题