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 ...
随机推荐
- Storm编程模型及组件流程图
一.Storm编程模型 二.Storm组件流程图
- Linux内核中namespace之PID namespace
前面看了LInux PCI设备初始化,看得有点晕,就转手整理下之前写的笔记,同时休息一下!!~(@^_^@)~ 这片文章是之前写的,其中参考了某些大牛们的博客!! PID框架的设计 一个框架的设计会考 ...
- Python并行编程(六):线程同步之条件
1.基本概念 条件指的是应用程序状态的改变.其中某些线程在等待某一条件发生,其 他线程会在该条件发生的时候进行通知,一旦条件发生,线程会拿到共享资源的唯一权限. 2.示例代码 from threadi ...
- 从数学分析的角度来看Softmax
作者:无影随想 时间:2016年1月. 出处:https://zhaokv.com/machine_learning/2016/01/softmax-calculous-perspective.htm ...
- Angular 回到顶部 滚动到特定的页面位置
$timeout(function() { // $location.hash('bottom'); // $anchorScroll(); // var a=angular.element(&quo ...
- Yii2 教程 - yii2-redis 扩展详解
该教程已被合并到<Yii2 权威指南中文版>中!Yiichina 教程地址为<yii2-redis 扩展详解>! 一.简介 yii2-redis 扩展为 Yii2 框架提供了 ...
- UVA10905: Children's Game(排序)
题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68990#problem/A 题目需求:,给n个数字,将它们重新排序得到一个最大的数 ...
- python全栈开发从入门到放弃之推导式详解
variable = [out_exp_res for out_exp in input_list if out_exp == 2] out_exp_res: 列表生成元素表达式,可以是有返回值的函数 ...
- Zen cart 根据数量打折插件
Quantity Discounts 可以根据顾客购买多少来打折,很不错. 假如顾客买了3个以上的产品,就给他10%折扣,设置如下: Turn On Quantity Discount 1. In t ...
- 关于bootstrap插件datepicker
<input readonly size="16" type="text" name="time" id="time&q ...