现在我想将 DataReader 转换为 Entity 。我有这样的方法:
private static void ReadInt32(ILGenerator il, LocalBuilder item,
List<DbColumnInfo> columnInfoes, LocalBuilder[] colIndices, int i)
{
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);
}
并像这里一样调用方法,
if (IsCompatibleType(columnInfoes[i].Type, typeof(int)))
{
// item.%Property% = arg.GetInt32(%index%);
ReadInt32(il, item, columnInfoes, colIndices, i);
}
不幸的是,如果 DB 中归档的数据为 NULL,则会出现异常。由于 int 类型不能为 NULL 值,但我将其转移到 int?。然后事实证明我的调用方法效果很好。
但是在这里我想要一个扩展名,即当 DB 中的数据归档为 NULL 时,我们可以使用自定义属性来指示默认值。所以我重新定义了 ReadInt32 如下,但令我惊讶的是,总是出现 JIT 内部异常。我对IL不熟悉,我真的很期待对大家的帮助,非常感谢。
将代码更改如下,但仍然存在错误,异常类型为:System.EntryPointNotFoundException:
var local = il.DeclareLocal(columnInfoes[i].Type);//int i
Label intNull = il.DefineLabel();//int intNull;
Label intCommon = il.DefineLabel();
il.Emit(OpCodes.Ldloca, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);
il.Emit(OpCodes.Callvirt, DataRecord_IsDBNull);// int i=isdbnull?
il.Emit(OpCodes.Brtrue_S, intNull);// int i=isdbnull?intNull
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc_S, colIndices[i]);//int i=isdbnull?1000:getInt(32)
il.Emit(OpCodes.Callvirt, DataRecord_GetInt32);//int i=isdbnull?1000:getInt32(i);
il.Emit(OpCodes.Br_S, intCommon);
il.MarkLabel(intNull);;
il.Emit(OpCodes.Ldc_I4, 123);//intNull=DefaultValue columnInfoes[i].DefaultValue
il.MarkLabel(intCommon);
il.Emit(OpCodes.Stloc_S, item);
//il.Emit(OpCodes.Ldloc_S, item);
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Callvirt, columnInfoes[i].SetMethod);