Как сопоставить датируемые столбцы со свойствами объекта DTO типа T - PullRequest
0 голосов
/ 09 мая 2019

Как можно сопоставить датируемые столбцы со свойствами объекта DTO типа T, используя запрос LINQ или лямбда-выражение. Это должно автоматически сопоставляться с любым DTO. Если есть способ сделать это без жесткого кодирования имен столбцов 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 Ответ

0 голосов
/ 09 мая 2019

Мы можем использовать отражение для преобразования столбцов таблицы данных в свойство объекта 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"},
    };
}
...