如何将数据表列映射到T型DTO对象的属性
如何使用LINQ查询或Lambda表达式将数据表列与类型T的DTO对象的属性映射.这应该会自动与任何DTO映射.如果有一种方法可以不对数据表的列名进行硬编码
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
}
}
我们可以使用反射将数据表的列转换为DTO对象的属性.就我而言,我实际上是将其转换为列表,下面是代码:
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;
}
请注意,由于我们正在执行new T()
,因此需要对类进行约束.为完整起见,columnMap的约束和定义是:
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; }
...
...
}
列名称映射存储为:
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"},
};
}