如何使用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
}
}
答案 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"},
};
}