How to Convert DataReader Result to Entity? ->use Emit
Now I want to Convert a DataReader to an Entity . I have a method like this:
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);
}
and call the method like here,
if (IsCompatibleType(columnInfoes[i].Type, typeof(int)))
{
// item.%Propert开发者_Go百科y% = arg.GetInt32(%index%);
ReadInt32(il, item, columnInfoes, colIndices, i);
}
unfortunately, there will come up an Exception if the Data Filed in DB is NULL. As int type can't be NULL value but I made it transfer to int?. then turns out that my calling method works well.
but here I want an extension that is while Data Filed in DB is NULL, we can use Custom attribute to indicate a default value. So I re-defined ReadInt32 as following, But to my surprise, there always comming up JIT inner Exception. I'm not familiar with IL, I really looking forward some help for you all, really appreciate.
change the code's as following,but still exist error,the exception type is : 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);
Just use Dapper. If it's good for SO, it will be good for you, too ;-)
精彩评论