前段时间通过网上查找,使用emit将Datatable,DataReader转换成List<T>了。这是从数据库到展示。

但是最近整理Hikari(我写的数据库连接池),发现c#里面数据库客户端驱动一般会提供一个BulkCopy的类,一般接口是DataTable,可以批量插入。所以又研究了如何把List<T>转DataTable.

一般方法是全部反射,我就不说了。这里只说emit,记录下下次用。

这里创建动态方法(委托)有个范围问题。我举个例子

假如有Pseron类。

public class Person

    {

        public string Name { get; set; }

        public int Age { get; set; }

        public int Score { get; set; }

    }

1.方法是这样的

public static void PersonToDataRow(Person person, DataTable dt)

        {

            DataRow row=  dt.NewRow();

            row["Name"] = person.Name;

            row["Age"] = person.Age;

            row["Score"] = person.Score;

            dt.Rows.Add(row);

        }

2.方法是这样的

public static void PersonToDataRow(Person person, DataRow row)

        {

          

            row["Name"] = person.Name;

            row["Age"] = person.Age;

            row["Score"] = person.Score;

        }

这两种就有范围问题。

第一类创建动态方法代码如下:

需要有一个委托定义: public delegate void LoadDataRow<T>(T obj,DataTable dr);

创建代码

 public static DynamicMethod ConvertDataRow<T>()
{
DynamicMethod method = new DynamicMethod(typeof(T).Name+"ToDataRow", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null,
new Type[] { typeof(T), typeof(DataRow) }, typeof(EntityContext).Module, true);
ILGenerator generator = method.GetILGenerator();
LocalBuilder reslut = generator.DeclareLocal(typeof(DataRow));
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, typeof(DataTable).GetMethod("NewRow"));
generator.Emit(OpCodes.Stloc, reslut);
foreach (var p in typeof(T).GetProperties())
{
generator.Emit(OpCodes.Ldloc, reslut); generator.Emit(OpCodes.Ldstr, p.Name);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, p.GetGetMethod());//
if (p.PropertyType.IsValueType)
generator.Emit(OpCodes.Box, p.PropertyType);//一直在折腾这个地方,哎
else
generator.Emit(OpCodes.Castclass, p.PropertyType); generator.Emit(OpCodes.Call, typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
}
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, typeof(DataTable).GetMethod("get_Rows"));
generator.Emit(OpCodes.Ldloc, reslut);
generator.Emit(OpCodes.Call, typeof(DataRowCollection).GetMethod("Add", new Type[] { typeof(DataRow) }));
generator.Emit(OpCodes.Ret); return method; }

调用上面代码创建委托即可。

第二类创建代码:

需要定义一个委托:public delegate void EntityToRow<T>(T obj, DataRow row);

创建代码:

  private static DynamicMethod BuildMethodToRow<T>()
{
DynamicMethod method = new DynamicMethod(typeof(T).Name+ "ConvertToDataRow", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard,null,
new Type[] { typeof(T),typeof(DataRow) }, typeof(EntityContext).Module, true);
ILGenerator generator = method.GetILGenerator();
foreach (var p in typeof(T).GetProperties())
{
var endIfLabel = generator.DefineLabel();
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldstr, p.Name);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, p.GetGetMethod());//获取
if (p.PropertyType.IsValueType || p.PropertyType == typeof(string))
generator.Emit(OpCodes.Box,p.PropertyType);//装箱
else
generator.Emit(OpCodes.Castclass, p.PropertyType);
generator.Emit(OpCodes.Call, dataRowAssembly.SetValueMethod);
}
generator.Emit(OpCodes.Ret);
return method;
}

调用上面代码创建委托即可。

c#将List转换成DataTable(采用Emit)的更多相关文章

  1. c#将List转换成DataTable

    前面写了一篇List<T>转换成DataTable,这里主要是完善了前面的代码. 同样使用了emit,我把代码整理后上传了git. 另外增加了特性的设计. 设计了三类特性ColumnTyp ...

  2. 带复杂表头合并单元格的HtmlTable转换成DataTable并导出Excel

    步骤: 一.前台JS取HtmlTable数据,根据设定的分隔符把数据拼接起来 <!--导出Excel--> <script type="text/javascript&qu ...

  3. C#_List转换成DataTable

    /// <summary> /// 讲list集合转换成datatable /// </summary> /// <param name="list" ...

  4. 将List转换成DataTable

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  5. list转换成DataTable

    list转换成DataTable类如下: public static DataTable ToDataTable<T>(this IList<T> datas) { DataT ...

  6. 将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据

    领导让在存储过程中批量添加数据,找出效率最高的,我看到后台代码后,发现可以将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据,知道还有其 ...

  7. C# DataTable转换成实体列表 与 实体列表转换成DataTable

    /// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...

  8. 获取报告 Stream转string,利用字符串分割转换成DataTable

    protected void Button1_Click(object sender, EventArgs e) { MemoryStream stream = new MemoryStream(); ...

  9. C#:CsvReader读取.CSV文件并转换成DataTable

    原文引用:https://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader using LumenWorks.Framework.IO.Csv; ...

  10. 将泛类型集合List类转换成DataTable

    /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...

随机推荐

  1. Unable to update index for central http://repo1.maven.org/maven2/ 解决方法

    不知道什么原因 MyEclipse(eclipse) 中的 maven 插件突然不能用了,修改 pom.xml 无任何反应 控制台报 Unable to update index for centra ...

  2. Maximum Subarray 连续子数组最大和

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  3. 为订阅内虚拟机批量安装并配置 Microsoft Anti-Malware 扩展

    本文提供了对订阅内的 Windows 经典部署虚拟机和资源管理器部署虚拟机执行批量安装并配置 Microsoft Anti-Malware 扩展的 PowerShell 脚本. 关于安装 Window ...

  4. SCOM发送邮件通知

    运行方式配置:1. 新建账户--Windows域账户,安全级别较高,将其分发到SCOM管理服务器2. 配置文件--通知账户--将上一步新建的账户添加到该配置文件中的 运行方式账户,管理 所有目标对象 ...

  5. 一些实用的adb命令

    一.前提: 1.打开手机调试模式,确保手机已正常连接电脑,可在电脑上通过adb devices命令查看,结果如下说明连接成功: List of devices attached90xxxxc9 dev ...

  6. Exchange邮件系统日志查看及管理

    1.查看邮件服务器上某个时间段内的所有邮件信息: Get-MessageTrackingLog -ResultSize Unlimited -Start "3/6/2015 8:40AM&q ...

  7. August 15th 2017 Week 33rd Tuesday

    Would rather have done a regret, do not miss the regret. 宁愿做过了后悔,也不要错过了后悔. Yesterday, I read several ...

  8. ZT 第9章 Framework的启动过程

    所在位置: 图书 -> 在线试读 -> Android内核剖析 第9章 Framework的启动过程 9.3 zygote的启动 前面小节介绍了Framework的运行环境,以及Dalvi ...

  9. Jarsigner签名使用

    转载请标明出处: http://www.cnblogs.com/why168888/p/6548544.html 本文出自:[Edwin博客园] 如何签名: jarsgner-verbose-keys ...

  10. Oracle Golden Gate概要

    Oracle GoldenGate简介 Oracle Golden Gate用于源数据库与目标数据库的数据复制备份:可以在异构的环境(各种操作系统和数据库)之间实现数据亚秒级的实时复制备份:以及可以在 ...