c#将List转换成DataTable(采用Emit)
前段时间通过网上查找,使用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)的更多相关文章
- c#将List转换成DataTable
前面写了一篇List<T>转换成DataTable,这里主要是完善了前面的代码. 同样使用了emit,我把代码整理后上传了git. 另外增加了特性的设计. 设计了三类特性ColumnTyp ...
- 带复杂表头合并单元格的HtmlTable转换成DataTable并导出Excel
步骤: 一.前台JS取HtmlTable数据,根据设定的分隔符把数据拼接起来 <!--导出Excel--> <script type="text/javascript&qu ...
- C#_List转换成DataTable
/// <summary> /// 讲list集合转换成datatable /// </summary> /// <param name="list" ...
- 将List转换成DataTable
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- list转换成DataTable
list转换成DataTable类如下: public static DataTable ToDataTable<T>(this IList<T> datas) { DataT ...
- 将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据
领导让在存储过程中批量添加数据,找出效率最高的,我看到后台代码后,发现可以将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据,知道还有其 ...
- C# DataTable转换成实体列表 与 实体列表转换成DataTable
/// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...
- 获取报告 Stream转string,利用字符串分割转换成DataTable
protected void Button1_Click(object sender, EventArgs e) { MemoryStream stream = new MemoryStream(); ...
- C#:CsvReader读取.CSV文件并转换成DataTable
原文引用:https://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader using LumenWorks.Framework.IO.Csv; ...
- 将泛类型集合List类转换成DataTable
/// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...
随机推荐
- react 共享数据流
层层传递Props 单向数据流层层传递,繁琐不好管理. Context 什么是context? context是react提供的组件通信api context有什么用? 解决{组件.js}中多层级组件 ...
- Android架构设计之插件化、组件化
如今移动app市场已经是百花齐放,其中有不乏有很多大型公司.巨型公司都是通过app创业发展起来的:app类型更加丰富,有电子商务.有视频.有社交.有工具等等,基本上涵盖了各行各业每个角落,为了更加具有 ...
- Linux修改Oracle用戶
Linux下SSH登陆后: su - Oracle; sqlplus /nolog; conn system/密码; 或者 connect/as sysdba; alter user 用户名 iden ...
- js实现查找字符串出现最多的字符和次数
代码如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=" ...
- 五大常用算法之四:回溯法[zz]
http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试 ...
- 准备你的 In-app Billing 程序
准备好你的内购应用 在开始使用 In-app Billing 服务之前,你需要先把包含 In-app Billing Version 3 API 的库添加到你的Android工程中.你还需要设置你的应 ...
- 企业级Nginx增加日志选项
日志介绍 目的:将用户的访问信息记录到指定的文件中由ngx_http_log_module模块负责 访问日志参数: access_log:指定日志文件的路径和使用何种日志格式记录日志 log_form ...
- Windows 7 控制面板Update选项灰色解决办法
具体解决方法是开始-运行-regedit,打开注册表编辑器,在注册表里找: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows,展开Windo ...
- 乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number
乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number 一.前言 如何让两个或者多个集合中的随机挑选的元素结合到一起,并且得到所有的可能呢? ...
- [EffectiveC++]item12:copy all parts of an object
在小书C++中,4.2.2 派生类的构造函数和析构函数的构造规则(103页) 在定义派生类对象时,构造函数执行顺序如下: 基类的构造函数 对象成员的构造函数 派生类的构造函数.