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 ...
随机推荐
- 一些 Mysql 维护命令
----------------------------------------------------------------------------使用mysql客户端程序------------ ...
- 把KB转化为KB及以上单位
/** * 把KB转化为KB及以上单位 * @param int $kb * @return string $new_val */ function return_over_kb($kb) { $kb ...
- ubuntu16下面 redis 无法链接到客户端问题
1.今天从github上面下载了一个项目,链接到自己的tomcat里面的redis,结果在虚拟机里面可以链接成功,但是在客户端总是提示链接失败.google之后,原来是 因为 需要在redis里面设置 ...
- Linux常用命令(二)————压缩+解压
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- Effective C++(1-2) 编译器替换预处理器
1 C++最主要的四部分: C Object-Oriented C++: 面向对象 Template C++:泛型编程 STL C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2 尽量 ...
- 【转】outlook 2016 配置自动发现
今天一部门经理换了高大上的终端,办公软件安装的是office 2016,在配置outlook的时候,懵逼了,没有exchange 选项,使用自动发现配置的时候,电脑没有加域,各种尝试,一直过不去,哎, ...
- Exchange2016 & Skype for business集成之二 OWA集成IM
Microsoft Outlook Web App 和IM集成部署或升级Exchange server 2016与Skype for business 2015后使用原来2013版本方法集成OWA网页 ...
- PostgreSQL 连接问题 FATAL: no pg_hba.conf entry for host
The server doesn't grant access to the database: the server reports FATAL: no pg_hba.conf entry for ...
- POJ2074 Line of Sight
嘟嘟嘟 题意:用一条水平线段表示以栋房子:\((x_0, y_0)(x_0', y_0)\).然后有一条低于房子的水平线段\(l_0\),代表你可以到的位置.接下来输入一个数\(n\),一下\(n\) ...
- 【jQuery】结合accordion插件分析写插件的方法及注意事项
1.jQuery插件的命名方式:jquery.[插件名].js 2.对象方法附加在jQuery.fn上,全局函数附加在jQuery对象本身上 3.插件内部this指向的是通过选择器获取的jQuery对 ...