如何将数据表列映射到T型DTO对象的属性

时间:2019-05-09 00:58:41

标签: c# linq reflection mapping dto

如何使用LINQ查询或Lambda表达式将数据表列与类型T的DTO对象的属性映射。这应该会自动与任何DTO映射。如果有一种方法可以不对数据表的列名进行硬编码

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 个答案:

答案 0 :(得分:0)

我们可以使用反射将数据表的列转换为DTO对象的属性。就我而言,我实际上是将其转换为列表,这是代码:

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

请注意,由于我们正在做new T(),因此需要对类进行约束。完整性的columnMap约束和定义为:

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

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

列名称映射存储为:

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