How to map datatable columns to properties of DTO object of Type T

风格不统一 提交于 2020-01-02 20:30:17

问题


How can map datatable columns with the properties of DTO object of Type T using LINQ query or Lambda expression. This should automatically map with any DTO. If there is a way to do this without hardcoding of column names of datatable

DataTable dt = db.GetEmployees();


foreach(DataRow dr in dt.Rows)
{
    var obj = new T();
    PropertyInfo[] prop  = obj.GetType().GetProperties();



    var results = dt.AsEnumerable().Select(dr => new T
        {
            ///How to directly map type T properties in prop with columns in datatable dt

        FirstName = ?

        //Expecting something like this
                //FirstName = columnName of dt here

        }     
}

回答1:


We can use reflection to convert the data table columns into a DTO object's property. In my case I was actually converting it into a List, here's the code:

        private IEnumerable<T> ConvertToEnumerable(DataTable dt)
        {
            List<T> ls = new List<T>();

            // get all the column names from datatable
            var columnNames = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList();

            //dto so all properties should be public
            var dtoProperties = typeof(T).GetProperties(); 

            foreach (DataRow row in dt.Rows)
            {
                // create  a new DTO object
                var item = new T();

                // for each property of the dto
                foreach (var property in dtoProperties)
                {
                    var objPropName = property.Name;

                    // I am using the column map dictionary to convert the 
                    // DTO property name into my datatable column name
                    // but you can omit this step if your names in DTO 
                    // and datatable columns are same
                    var dbPropName = ColumnMap[property.Name];
                    if (columnNames.Contains(dbPropName))
                    {
                        if (row[dbPropName] != DBNull.Value)
                        {
                            // set the value
                            property.SetValue(item, row[dbPropName], null);
                        }
                    }
                }

                // add the DTO to the list
                ls.Add(item);
            }
            return ls;
        }

Do note that since we are doing new T(), the constraint on class is required for this. The constraint and the definition of columnMap for completeness is:

public class Repository<T> : IRepository<T> where T : new()
    {
        private DbManager context = null;

        public Dictionary<string, string> ColumnMap { get; set; }
        ...
        ...
     }

And the column name mappings are stored as:

public class RepositoryMap
{

    public static Dictionary<string, string> ObjectToDatatableMap = new Dictionary<string, string>
    {
        // keep in mind that key is the DTO property
        // value is the datatable columm name
        {"Id", "ID"},
        {"Owner", "OWNER"},
        {"QueryName", "QUERY NAME"},
        {"PhoneNumber", "Phone Number"},
    };
}


来源:https://stackoverflow.com/questions/56050805/how-to-map-datatable-columns-to-properties-of-dto-object-of-type-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!