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 ...
随机推荐
- golang环境安装
到官方https://golang.org/dl/下载安装包 cd /usr/local/src wget https://storage.googleapis.com/golang/go1.8.li ...
- Ponds----hdu5438(拓扑排序)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5438 题意:有n个池塘和m个管道:每个池塘的价值是v, 现在由于资金问题要删除池塘:但是删除的池塘 ...
- 转载--菜鸟Linux上使用Github
1.安装Git:Ctrl + Alt + T使用终端:使用命令 sudo apt-get install git 2.创建GitHub帐号:登陆git主页: https://github.com/,自 ...
- Jmeter(一)http接口添加header和cookie
HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post)的时候,往往后端需要一些验证信息,比如说web服务器需要带过去c ...
- STL: fill,fill_n,generate,generate_n
fill Assigns the same new value to every element in a specified range. template<class ForwardIter ...
- 【android】 如何把gif图片下载到本地
以上图片大家可以看到,虽然是个jpg格式的文件,但是本质上是个动图. 但是发现在咱的图片模块下,本地存储的图片只有一帧,问题出在哪里呢? http获取到的byte[]数据是没问题的 断点跟踪了下,发现 ...
- How can For each...
Answer: I understand the IEnumerator/IEnumerable methods and properties and also how they are inte ...
- jstl c:choose>、<c:when>和<c:otherwise>标签的简单使用介绍
<c:choose>.<c:when>和<c:otherwise>在一起连用,可以实现Java语言中的if-else语句的功能.例如以下代码根据username请求 ...
- Linux中LVM2原理
一.LVM原理 [MD]:Multi Device 多设备 Mdadm是一个用户空间工具,是RAID的管理工具,与真正的RAID工作没有太大关系.真正的RAID集成在linux内核中 [DM]Devi ...
- php 安装Memcache扩展
转载地址:http://www.tuicool.com/articles/EB3imm 文章概述:由于当前机器安装的php,是用yum安装,现在需要使用到memadmin做一些监控, memadmin ...