直接上代码:

根据属性进行映射:DataTable转化成实体List

public static class DataTableExtension
{
public static List<T> ToList<T>(this DataTable dt)
{
if (dt == null || dt.Rows.Count == )
{
return null;
} List<T> entites = new List<T>(); foreach (DataRow dr in dt.Rows)
{
T t = (T)Activator.CreateInstance(typeof(T));
for (int i = ; i < dr.Table.Columns.Count; i++)
{
PropertyInfo propertyInfo = t.GetType().GetProperty(dr.Table.Columns[i].ColumnName);
if (propertyInfo != null && dr[i] != DBNull.Value)
propertyInfo.SetValue(t, dr[i], null);
} entites.Add(t);
}
return entites;
}
}
}

但是需求往往没有这么简单,如果属性名称和列名不一致,如列名是excel导入过来的,就很有可能是汉字。

我的解决办法就是,在实体模型中,添加Attribute,来注明每个属性和列名的对应关系,如下:

public class Bill
{
[Column("序号")]
public int Id { get; set; } [Column("姓名")]
public string PatientName { get; set; } [Column("结算日期")]
public DateTime BillDate { get; set; } }

现在有两种映射方式了,为了使代码不要太难看,只能重构一下:

public static class DataTableExtension
{
public static List<T> ToList<T>(this DataTable dt, IRowMapper<T> rowMapper)
{
if (dt == null || dt.Rows.Count == )
{
return null;
} List<T> entites = new List<T>(); foreach (DataRow dr in dt.Rows)
{
var t = rowMapper.MapRow(dr); entites.Add(t);
}
return entites;
}
}

添加了一个接口IRowMapper,表明是属性映射,还是自定义的映射。

来看下自定义映射具体的实现:

public class ColumnAttributeMapper<T> : IRowMapper<T>
{
private static Dictionary<string, Dictionary<string, string>> ColumnPropertyMapper= new Dictionary<string, Dictionary<string, string>>(); public ColumnAttributeMapper()
{
if (!ColumnPropertyMapper.ContainsKey(typeof(T).Name))
{
Dictionary<string, string> dict = new Dictionary<string, string>(); var props = typeof(T).GetProperties(); foreach (var prop in props)
{
var attribute = prop.GetCustomAttributes(true).OfType<ColumnAttribute>().FirstOrDefault();
dict.Add(attribute.Name, prop.Name); }
ColumnPropertyMapper.Add(typeof(T).Name, dict);
} } public T MapRow(DataRow dr)
{
T t = (T)Activator.CreateInstance(typeof(T));
for (int i = ; i < dr.Table.Columns.Count; i++)
{
if (ColumnPropertyMapper.ContainsKey(t.GetType().Name))
{
var dict = ColumnPropertyMapper[t.GetType().Name];
var property = dict[dr.Table.Columns[i].ColumnName]; PropertyInfo propertyInfo = t.GetType().GetProperty(property);
if (propertyInfo != null && dr[i] != DBNull.Value)
propertyInfo.SetValue(t, dr[i], null);
}
} return t;
}
}

在构造函数中定义了一个静态的字典,用于存储实体中列名和属性名的对应关系(这里有点绕,我还没想到更好的方法!),

具体调用方法:

  public static void TestPropertyMapper()
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("PatientName", typeof(string));
dt.Columns.Add("BillDate", typeof(DateTime)); dt.Rows.Add(, "HKK", DateTime.Now);
dt.Rows.Add(, "WQ", DateTime.Now);
dt.Rows.Add(, "HS", DateTime.Now); List<Bill> bills = dt.ToList<Bill>(rowMapper: new PropertyColumnMapper<Bill>());
}
private static void TestColumnMapper()
{
DataTable dt = new DataTable();
dt.Columns.Add("序号", typeof(int));
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("结算日期", typeof(DateTime)); dt.Rows.Add(, "HKK", DateTime.Now);
dt.Rows.Add(, "WQ", DateTime.Now);
dt.Rows.Add(, "HS", DateTime.Now); List<Bill> bills = dt.ToList<Bill>(rowMapper: new ColumnAttributeMapper<Bill>());
}

代码上传到github:https://github.com/hankuikuide/ExcelAccessor/tree/master/Han.DataAccess

最新文章

  1. 移动web app开发必备 - 异步队列 Deferred
  2. AppScan 测试需要输入用户名密码的网站
  3. JavaScript事件---事件绑定和深入
  4. lcd 图片
  5. IIS网站部署注意点
  6. 客户端的数据来源:QueryString, Form, Cookie Request[]与Request.Params[]
  7. MongoDB基本操作
  8. HDOJ --- 2577
  9. 经典SQL语句大全之提升
  10. struts2,hibernate,spring整合笔记(4)--struts与spring的整合
  11. JS常用的方法
  12. php 的设计模式
  13. WPF点滴
  14. Net分布式系统之六:微服务之API网关
  15. Mego(05) - Mego for Visual Studio Extension
  16. fastcgi php-cgi与php-fpm区别和之间的关系
  17. CSS样式简介
  18. AI 线性回归
  19. MySQL数据库以及表的管理
  20. 浏览器存储:cookie

热门文章

  1. 3.2 - FTP文件上传下载
  2. 小技巧-如何加快github下载代码的速度(转)
  3. codechef : Marbles 题解
  4. 除去DataTable中的空行!
  5. 简单的SQL注入学习
  6. win下如何解决在chrome的同源访问问题
  7. php内存溢出,出现Allowed memory size of 8388608 bytes exhausted错误的解决办法
  8. HDU2425:Hiking Trip(简单bfs,优先队列实现)
  9. PAT 1136 A Delayed Palindrome[简单]
  10. PAT 1146 Topological Order[难]