DataTable扩展:转化实体ToList
直接上代码:
根据属性进行映射: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
DataTable扩展:转化实体ToList的更多相关文章
- DataTable数据转换为实体
我们在用三层架构编写软件时,常常会遇到例如以下问题,就是三层之间的參数传递问题:假设我们在D层查询出数据是DataTable类型的,那么我们在B层甚至U层使用这条数据时,就要用DataTable类型来 ...
- DataTable转换为Model实体对象
记得在学校的时候,接触得最多的就是SqlHelper,每次在读取的时候不管是DataTable还是DataReader转换为实体对象的时候是最恼火的,因为要写很多代码,而且没有什么意义.后面接触到了反 ...
- C# DataTable转换成实体列表 与 实体列表转换成DataTable
/// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...
- DataTable扩展方法ToList<T>()、ToJSON()、ToArrayList()
/// <summary> /// 扩展方法类 /// </summary> public static class CommonExtension { /// <sum ...
- DataTable填补了实体类返回泛型集合
坤哥见我昨天找了一段代码,如下面: 略微解释下,这段代码时D层查询结束后,将datatable查询到的结果赋值给实体对象的属性,然后返回实体的过程.坤哥看了之后问我,假设实体有500多个属性,难道也要 ...
- C#把 DataTable转换为Model实体
public static List<T> GetModelFromDB<T>( DataTable dt ) { List<T> data = new List& ...
- (转)DATATABLE(DATASET)与实体类之间的互转.
转自:http://www.cnblogs.com/zzyyll2/archive/2010/07/20/1781649.html dataset和实体类 之间的转换 //dataset转实体类 代 ...
- DataTable转换成实体
public static class DataTableToEntity { /// <summary> /// 将DataTable数据源转换成实体类 /// </summary ...
- C# DataTable扩展方法
在日常搬砖中,总结了一些简单的扩展方法. public static bool IsNullOrEmpty(this DataTable dt) { ; } public static bool Is ...
随机推荐
- 利用wget批量下载http目录下文件
原理:下载你需要down的目录页面的index.html,可能名字不是如此!!!之后用wget下载该文件里包含的所有链接! 例如:wget -vE -rLnp -nH --tries=20 --tim ...
- SpringBean 定义继承
Bean定义继承 bean定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息例如初始化方法,静态工厂方法名,等等.子bean的定义继承副定义的配置数据.子定义可以根据需要重写一些值 ...
- wordpress 主题开发
https://yusi123.com/3205.html https://themeshaper.com/2012/10/22/the-themeshaper-wordpress-theme-tut ...
- yii2 框架中的即点即改入库
视图层 <td><span class='num' id="<?php echo $value['goods_attr_id']?>">< ...
- 300. Longest Increasing Subsequence(LIS最长递增子序列 动态规划)
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
- NGUI混合FingerGesture《卷二》分离触摸事件
背景 在使用NGUI按钮组件的时候,点击按钮同时触发FingerGesture的Touch事件, 通俗点讲,NGUI点击之后,点击事件被FingerGesture又执行了一遍. 解决思路 持有一个全局 ...
- 有界、无界队列对ThreadPoolExcutor执行的影响
本文转载自https://blog.csdn.net/kusedexingfu/article/details/72491864 Java提供了4钟线程池: newCachedThreadPool n ...
- RedisTemplate访问Redis数据结构
https://www.jianshu.com/p/7bf5dc61ca06 Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字 ...
- servlet的总结
tomcat在启动的时候 加载webapp下面的web.xml,加载里面定义的servlet. web.xml文件有两部分:servlet类定义和servlet映射定义每个被载入的servlet类都有 ...
- 20145307第八周JAVA学习报告
20145307<Java程序设计>第8周学习总结 教材学习内容总结 通用API 日志API 1.java.util.logging包提供了日志功能相关类与接口,使用日志的起点是logge ...