类库扩展自Datatable,可以直接用Datatable.ToList<T>()进行转换。为了方便把DataReader装入Datatable,开扩展了一个LoadForReader(this DataTable dt, IDataReader reder),用法很简单。看例子。

  1. public override void Execute()
  2. {
  3. using (var conn = DbConnection)
  4. {
  5. conn.Open();
  6. MySqlCommand Command = new MySqlCommand(QuerySql, conn);
  7. var data = new DataTable().LoadForReader(Command.ExecuteReader());
  8. foreach (var item in data.ToList<Admin>(new List<ConvertMapping> { ConvertMapping.Convert("userId", "Id") }))
  9. {
  10. AddEntityToContext(item);
  11. }
  12. }
  13. SavaChangs();
  14. }

DataTable.ToList<T>()有两个可选参数,第一个是“映射关系集合”,另外一个是“自定义转换器”。下面分别说下有什么作用。

1:映射关系集合

假设现在数据库一张Student表,Student表拥有Id,StudentName,StudetnAge,同样,我们在项目中有一个Student类,Student类有Id,Name,Age字段。在进行转换的时候,会自动找同名的属性进行映射复制,Id可以进行赋值,但是StudentName和Age却不行。所以我们要把StudentName和Name建立映射关系。

  1. var mappings = new List<ConvertMapping>{
  2. ConvertMapping.Convert("StudentName","Name"),
  3. ConvertMapping.Convert("StudentAge","Age")
  4. };

2:自定义转换器

假设我们在转换的时候,需要把数据库里面StudentAge字段小于18的在转换的时候全部改成18,就需要用到”自定义转换器”,用法如下:

  1. new DataTable().ToList<Admin>(null, (c, r) =>
  2. {
  3. if (r["StudentAge"] != DBNull.Value && Convert.ToInt32(r["StudentAge"]) < )
  4. {
  5. c.Age = ;
  6. }
  7. else
  8. {
  9. c.Age = Convert.ToInt32(r["StudentAge"]);
  10. }
  11. });

下面贴上代码:

  1. public static class DatatableExtend
  2. {
  3. /// <summary>
  4. /// 表格转换成List
  5. /// </summary>
  6. /// <typeparam name="T"></typeparam>
  7. /// <param name="table"></param>
  8. /// <param name="mappings"></param>
  9. /// <returns></returns>
  10. public static List<T> ToList<T>(this DataTable table, IList<ConvertMapping> mappings = null, Action<T, DataRow> convetAc = null) where T : class, new()
  11. {
  12. List<T> result = new List<T>();
  13. if (table == null || table.Rows.Count == )
  14. {
  15. return result;
  16. }
  17. ConvertMapping mappingResult = null;
  18. foreach (DataRow row in table.Rows)
  19. {
  20. T tResult = new T();
  21. foreach (DataColumn column in table.Columns)
  22. {
  23. if (mappings != null)
  24. {
  25. mappingResult = mappings.Where(c => c.SourceColumnName.Equals(column.ColumnName, StringComparison.CurrentCultureIgnoreCase)).SingleOrDefault();
  26. }
  27. if (mappingResult == null)
  28. {
  29. mappingResult = ConvertMapping.Convert(column.ColumnName, column.ColumnName);
  30. }
  31. SetPropertyValue(tResult, mappingResult.NewSourceColumnName, row[mappingResult.SourceColumnName].ToString());
  32. }
  33. convetAc?.Invoke(tResult, row);
  34. result.Add(tResult);
  35. }
  36. return result;
  37. }
  38.  
  39. public static DataTable LoadForReader(this DataTable dt, IDataReader reder)
  40. {
  41. using (reder)
  42. {
  43. dt.Load(reder);
  44. }
  45. return dt;
  46. }
  47.  
  48. private static void SetPropertyValue<T>(T otype, string propertyName, object value)
  49. {
  50. if (otype == null)
  51. {
  52. throw new ArgumentNullException(nameof(otype));
  53. }
  54. var proInfo = otype.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
  55. if (proInfo != null)
  56. {
  57. if (proInfo.PropertyType == typeof(bool)&&Microsoft.VisualBasic.Information.IsNumeric(value))
  58. {
  59. value = Convert.ToInt32(value);
  60. }
  61. proInfo.SetValue(otype, Convert.ChangeType(value, proInfo.PropertyType));
  62. }
  63. }
  64. }
  65.  
  66. public class ConvertMapping
  67. {
  68. /// <summary>
  69. /// 源字段
  70. /// </summary>
  71. public string SourceColumnName { get; private set; }
  72.  
  73. /// <summary>
  74. /// 新字段
  75. /// </summary>
  76. public string NewSourceColumnName { get; private set; }
  77.  
  78. private ConvertMapping() { }
  79. public static ConvertMapping Convert<TType, TNewType>(Expression<Func<TType, string>> sourece, Expression<Func<TNewType, string>> newSource)
  80. {
  81. ConvertMapping mapping = new ConvertMapping();
  82. mapping.SourceColumnName = sourece.Parameters.SingleOrDefault()?.Name;
  83. mapping.NewSourceColumnName = newSource.Parameters.SingleOrDefault()?.Name;
  84. return mapping;
  85. }
  86.  
  87. public static ConvertMapping Convert(string sourece, string newSource)
  88. {
  89. ConvertMapping mapping = new ConvertMapping();
  90. mapping.SourceColumnName = sourece;
  91. mapping.NewSourceColumnName = newSource;
  92. return mapping;
  93. }
  94. }

分享一个DataTable转List强类型的类库的更多相关文章

  1. 分享一个导出数据到 Excel 的类库

    起源: 之前在做一个项目时,客户提出了许多的导出数据的需求: 导出用户信息 导出业务实体信息 各种查询都要能导出 导出的数据要和界面上看到的一致 可以分页导出 ... 为了应对用户的这些需求,我决定先 ...

  2. 分享一个oraclehelper

    分享一个拿即用的oraclehelper 首先要引用本机中的oralce access,如果是64位的话,也必须是64位运行,不然会报连接为空connection 等于null. using Orac ...

  3. 分享一个c#写的开源分布式消息队列equeue

    分享一个c#写的开源分布式消息队列equeue 前言 equeue消息队列中的专业术语 Topic Queue Producer Consumer Consumer Group Broker 集群消费 ...

  4. 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序

    分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图.      1.首先建立一个数 ...

  5. 分享一个SqliteHelper类

    分享一个SqliteHelper类 SQLite作为一个本地文件数据库相当好用,小巧.快速.支持事务.关系型,甚至可以运行在Android上.在很久以前的一个项目中,我们用过它来将接收到的数据做本地统 ...

  6. C# PDF Page操作——设置页面切换按钮 C# 添加、读取Word脚注尾注 C#为什么不能像C/C++一样的支持函数只读传参 web 给大家分享一个好玩的东西,也许你那块就用的到

    C# PDF Page操作——设置页面切换按钮   概述 在以下示例中,将介绍在PDF文档页面设置页面切换按钮的方法.示例中将页面切换按钮的添加分为了两种情况,一种是设置按钮跳转到首页.下页.上页或者 ...

  7. 分享一个简单的C#的通用DbHelper类(支持数据连接池)

    每次新项目的时候,都要从头去找一遍数据库工具类.这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池. 连接池配置 <connectionStrings> <add ...

  8. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  9. 分享一个MySQL分库分表备份脚本(原)

    分享一个MySQL分库备份脚本(原) 开发思路: 1.路径:规定备份到什么位置,把路径(先判断是否存在,不存在创建一个目录)先定义好,我的路径:/mysql/backup,每个备份用压缩提升效率,带上 ...

随机推荐

  1. 阿里云CentOS 7服务器挂载数据盘

    本次使用的是centOS 7.4 64位操作系统 第一步:查看磁盘情况 我们发现,我总共有三个磁盘,分别为/dev/vda(100G)./dev/vdb(200G)./dev/vdc(100G),而被 ...

  2. Bootstrap后台管理框架

    B-JUI http://www.xknaan.com/ B-JUI 前端框架,基于Bootstrap的Jquery UI框架,核心思想脱胎于DWZ(j-ui).   BJUI_SSM_DEMO 基于 ...

  3. EntityFramework Core2.0 多对多关系配置

    ​ 在EF6.0 中,多对多关系配置时,系统会自动生成第三张表,来将两张有互相约束关系的表联系起来,但是在EF Core2.0中,我们需要手动建立第三张表,比如说有两个模型Passage.cs和Cat ...

  4. Python的multiprocessing,Queue,Process

    在多线程multiprocessing模块中,有两个类,Queue(队列)和Process(进程): 在Queue.py中也有一个Queue类,这两个Queue的区别? from multiproce ...

  5. Mysql数据库的mysql Schema 究竟有哪些东西& 手工注入的基础要领

    #查看数据库版本号 mysql> select @@version; +------------+ | @@version  | +------------+ | 5.5.16-log | +- ...

  6. [luogu3941] 入阵曲

    题面 ​ 话说题目前面的那首诗还挺有意境的啊哈哈. ​ 可能今天要把中文的标点都换成英文的了, 先熟悉一下吧... ​ 好了, 进入正题, 求一个矩阵内有多少个子矩阵满足这个子矩阵的和模k为零.看到矩 ...

  7. [NOIp2009] $Hankson$の趣味题

    \(23333\)这是最近第二份在时间上吊打\(yjk\)的代码--啊哈哈哈哈哈哈哈 嗯,其实遇到这种单纯的\(gcd \ \ or \ \ lcm\)的题,我们都可以用一种比较简单的方法分析:唯一分 ...

  8. HDU2546(01背包加一点点变形)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2546 饭卡 Time Limit: 5000/1000 MS (Java/Others)    Me ...

  9. 【vue】vue项目引入 Element-UI

    根据vue项目的搭建教程,接下来记录下如何在Vue-cli创建的项目中引入Element-UI. 1.安装直接用命令 (推荐) npm install element-ui 2.直接在根目录下的pac ...

  10. 关于NSStringFromClass的一点见解

    今天做项目的时候遇到一个需求,就是子view视图弹出时,屏蔽掉父view的所有手势,然后想到用 UIGestureRecognizerDelegate代理方法,中间省一些文字(无奈脸),言归正传,NS ...