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

public override void Execute()
{
using (var conn = DbConnection)
{
conn.Open();
MySqlCommand Command = new MySqlCommand(QuerySql, conn);
var data = new DataTable().LoadForReader(Command.ExecuteReader());
foreach (var item in data.ToList<Admin>(new List<ConvertMapping> { ConvertMapping.Convert("userId", "Id") }))
{
AddEntityToContext(item);
}
}
SavaChangs();
}

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

1:映射关系集合

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

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

2:自定义转换器

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

new DataTable().ToList<Admin>(null, (c, r) =>
{
if (r["StudentAge"] != DBNull.Value && Convert.ToInt32(r["StudentAge"]) < )
{
c.Age = ;
}
else
{
c.Age = Convert.ToInt32(r["StudentAge"]);
}
});

下面贴上代码:

public static class DatatableExtend
{
/// <summary>
/// 表格转换成List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="table"></param>
/// <param name="mappings"></param>
/// <returns></returns>
public static List<T> ToList<T>(this DataTable table, IList<ConvertMapping> mappings = null, Action<T, DataRow> convetAc = null) where T : class, new()
{
List<T> result = new List<T>();
if (table == null || table.Rows.Count == )
{
return result;
}
ConvertMapping mappingResult = null;
foreach (DataRow row in table.Rows)
{
T tResult = new T();
foreach (DataColumn column in table.Columns)
{
if (mappings != null)
{
mappingResult = mappings.Where(c => c.SourceColumnName.Equals(column.ColumnName, StringComparison.CurrentCultureIgnoreCase)).SingleOrDefault();
}
if (mappingResult == null)
{
mappingResult = ConvertMapping.Convert(column.ColumnName, column.ColumnName);
}
SetPropertyValue(tResult, mappingResult.NewSourceColumnName, row[mappingResult.SourceColumnName].ToString());
}
convetAc?.Invoke(tResult, row);
result.Add(tResult);
}
return result;
} public static DataTable LoadForReader(this DataTable dt, IDataReader reder)
{
using (reder)
{
dt.Load(reder);
}
return dt;
} private static void SetPropertyValue<T>(T otype, string propertyName, object value)
{
if (otype == null)
{
throw new ArgumentNullException(nameof(otype));
}
var proInfo = otype.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
if (proInfo != null)
{
if (proInfo.PropertyType == typeof(bool)&&Microsoft.VisualBasic.Information.IsNumeric(value))
{
value = Convert.ToInt32(value);
}
proInfo.SetValue(otype, Convert.ChangeType(value, proInfo.PropertyType));
}
}
} public class ConvertMapping
{
/// <summary>
/// 源字段
/// </summary>
public string SourceColumnName { get; private set; } /// <summary>
/// 新字段
/// </summary>
public string NewSourceColumnName { get; private set; } private ConvertMapping() { }
public static ConvertMapping Convert<TType, TNewType>(Expression<Func<TType, string>> sourece, Expression<Func<TNewType, string>> newSource)
{
ConvertMapping mapping = new ConvertMapping();
mapping.SourceColumnName = sourece.Parameters.SingleOrDefault()?.Name;
mapping.NewSourceColumnName = newSource.Parameters.SingleOrDefault()?.Name;
return mapping;
} public static ConvertMapping Convert(string sourece, string newSource)
{
ConvertMapping mapping = new ConvertMapping();
mapping.SourceColumnName = sourece;
mapping.NewSourceColumnName = newSource;
return mapping;
}
}

分享一个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. Skype for Business Server 2015 企业语音部署和配置

    Skype for Business Server 2015包含的企业语音功能可实现更丰富的通信和协作.例如,可以将企业语音部署配置为启用Skype for Business Server 2015客 ...

  2. jQuery插件实例三:图片滚动[切换]效果一

    图片切换效果在很多网站上都能看到,是一种常见的广告/活动宣传方式,通常位于网页上端.这个插件是众多图片切换效果的形式中的一种,数据源可在前端配置,也可从后台通JSON格式传输数据,当然,数据格式是固定 ...

  3. November 10th 2016 Week 46th Thursday

    Live like you were dying, love because you do. 生如将逝,爱自本心. When faced with our darkest hour, hope is ...

  4. session过期,拦截ajax请求并跳转登录页面

    1.方法一 :1.1使用filter 和ajaxsetup 对ajax进行拦截并跳转登录页面 public void doFilter(ServletRequest request, ServletR ...

  5. [T-ARA][Apple is A]

    歌词来源:http://music.163.com/#/song?id=22704474 달콤달콤해 짜릿짜릿해 [tal-Kom-dal-Ko-mae jja-lid-jja-li-Tae] 반짝반 ...

  6. 【原创】MySQL 生产环境备份还原

    公司需要对生产环境的数据库进行备份,我接下了这份任务. 1. 首先谷歌了以下大家的备份方法 许多都使用到了Xtrabackup这个工具,超大型的公司可能有其他的的备份方法,这个工具对于中小型公司,甚至 ...

  7. 解决hibernate双向关系造成的一方重复执行SQl,或者死循环的问题

    系统采用struts-json hibernate3. 在对关联表配置manytoone onetomany双向关联的时候,在执行一方的时候,会发现打印出来的SQL语句多执行了一次或者多次.经过调试, ...

  8. JNLP应用程序无法打开的解决办法

    JNLP应用程序无法打开: 1.控制面板-Java-Java 选项卡-查看.用户选项卡勾选对应版本JDK(没有就添加,路径填类似:D:\Program Files\Java\jre6\bin\java ...

  9. vue2.* 事件结合双向数据绑定、模块化以及封装Storage实现todolist 待办事项 已经完成 和进行中持久化 06

    ceshi.vue <template> <div id="app"> <input type='text' v-model='todo' @keyd ...

  10. CVE-2017-8046 复现与分析

    环境搭建 使用的项目为https://github.com/spring-guides/gs-accessing-data-rest.git里面的complete,直接用IDEA导入,并修改pom.x ...