问题
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