C# Emit问题->DataReader 转Entity....

wangping_li 2011-06-29 02:33:04
正常读取reader.GetInt32的方法如下:

il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);


现在加了一个判断,就是当值为IsDBNull的时候,则取DefaultValue,代码如下:

var local = il.DeclareLocal(columnInfoes[i].Type);//int i
Label intNull = il.DefineLabel();//is null lable
Label intCommon = il.DefineLabel();//not null lable

il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);//将索引 0 处的局部变量i加载到计算堆栈上->i
il.Emit(OpCodes.Ldloc_S, colIndices[i]);//index ->为IsDBNull(index)的参数
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, intNull);//如果is null则转向intNull标签

il.Emit(OpCodes.Ldarg_0);//i
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Br_S, intCommon);//is not null则转向intCommon标签

//is null
il.MarkLabel(intNull);
il.Emit(OpCodes.Ldc_I4, columnInfoes[i].DefaultValue);//为null时这里赋值

//not null
il.MarkLabel(intCommon);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);


异常信息如下:

未经处理的异常: System.InvalidProgramException: JIT 编译器遇到内部限制。
在 (IDataReader )...

由于对IL不是很熟,希望大家帮忙看下,谢谢。。

...全文
621 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
bestdowt1314 2013-06-19
  • 打赏
  • 举报
回复
楼主在不,遇到一个类似问题,不知道怎么调试解决
Thomas_Chen 2011-06-30
  • 打赏
  • 举报
回复
帮顶 接分
wangping_li 2011-06-30
  • 打赏
  • 举报
回复
这东西就是不好调试,格式也不好看,ExpressionTree写出来比它优雅多了,呵呵
wangping_li 2011-06-30
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 sandy945 的回复:]

lz,现在怎么写的
[/Quote]
int32的代码如下,其它类型也差不多,就是DataTime和float要特殊处理下,DefaultValue的值自己通过custom attribute构造好:

var local = il.DeclareLocal(columnInfoes[i].Type);
Label intNull = il.DefineLabel();
Label intCommon = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);
il.Emit(OpCodes.Brtrue_S, intNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Br_S, intCommon);

il.MarkLabel(intNull);
il.Emit(OpCodes.Ldstr, columnInfoes[i].DefaultValue);
il.Emit(OpCodes.Call, Convert_ToInt32);
il.MarkLabel(intCommon);
il.Emit(OpCodes.Stloc, local);
il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);
kingdom_0 2011-06-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wangping_li 的回复:]

弄好了,散分咯,要的来接哦.//
[/Quote]对啊,分享下啊。
我的tcl 2011-06-30
  • 打赏
  • 举报
回复
观摩。。。
阿非 2011-06-30
  • 打赏
  • 举报
回复
lz,现在怎么写的
Ayanamikula 2011-06-30
  • 打赏
  • 举报
回复
mark。。
风骑士之怒 2011-06-30
  • 打赏
  • 举报
回复
久闻emit,先mark下
porschev 2011-06-30
  • 打赏
  • 举报
回复

好的。。接个分。。。
wangping_li 2011-06-30
  • 打赏
  • 举报
回复
弄好了,散分咯,要的来接哦.//
丿渎灬魂 2011-06-29
  • 打赏
  • 举报
回复
不懂 。帮顶 ............
wangping_li 2011-06-29
  • 打赏
  • 举报
回复
我想的是为NULL时直接将 columnInfoes[i].DefaultValue的值推到栈上。。
阿非 2011-06-29
  • 打赏
  • 举报
回复
晚些时候才能跟进,有问题请回复。
阿非 2011-06-29
  • 打赏
  • 举报
回复
il.Emit(OpCodes.Ldc_I4, columnInfoes[i].DefaultValue);//为null时这里赋值

=>

il.Emit(OpCodes.Initobj, columnInfoes[i].Type);
wangping_li 2011-06-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 liuchaolin 的回复:]

il.Emit(OpCodes.Ldc_I4, columnInfoes[i].DefaultValue);//为null时这里赋值

DefaultValue这里的默认值是指数据库字段里定义的默认值吗,会不会是你数据库里没有设默认值

il.Emit(OpCodes.Ldc_I4, 0);//这个可以这样写吗?
[/Quote]

这个值是我在custom attribute中配的,这里直接使用就好了,我都已经构造在columninfoes中去了
il.Emit(OpCodes.Ldc_I4, 0); 的意思是将int32类型,值为0的写入,和我的不一样
wangping_li 2011-06-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sandy945 的回复:]

C# code

il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Br_S, intCommon);//is not null则转向intCommon标签

=>
C# code

il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.……
[/Quote]

您好,你这种方式是针对转为 int? 类型的(可空值类型),我之前也是这么实现的,但是现在要改成非可空值类型支持默认值,也就是在Reader读取的时候,如果判断当前值为Null时,就使用columnInfoes[i].DefaultValue,否则还是使用原来,类似于:
item.属性 = reader.IsDBNull ? columnInfoes[i].DefaultValue: reader.GetInt32(colIndices[i]);
md5e 2011-06-29
  • 打赏
  • 举报
回复
il.Emit(OpCodes.Ldc_I4, columnInfoes[i].DefaultValue);//为null时这里赋值

DefaultValue这里的默认值是指数据库字段里定义的默认值吗,会不会是你数据库里没有设默认值

il.Emit(OpCodes.Ldc_I4, 0);//这个可以这样写吗?
阿非 2011-06-29
  • 打赏
  • 举报
回复

il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Br_S, intCommon);//is not null则转向intCommon标签

=>

il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);
il.Emit(OpCodes.Call, columnInfoes[i].Type.GetConstructor(new Type[] { Nullable.GetUnderlyingType(columnInfoes[i].Type) }));
il.Emit(OpCodes.Br_S, intCommon);
wangping_li 2011-06-29
  • 打赏
  • 举报
回复
我要的可能不是这个东西哦,我只是不知道哪一行指令写错,因为按逻辑来讲,是这样的,我也是按正常的写法,然后IL 反汇编程序看过生成的指令..继续等待,分不够再加呀...希望做过的给点提示...好久没来CSDN了,好多人都不在这了,哎.........
加载更多回复(3)

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧