如何将DataReader结果转换为实体? -> 使用发出

发布于 2024-11-17 10:20:25 字数 2226 浏览 4 评论 0原文

现在我想将 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);
                    }

不幸的是,如果数据库中的数据归档为空,则会出现异常。由于 int 类型不能为 NULL 值,但我将其转换为 int?。然后事实证明我的调用方法效果很好。

但这里我想要一个扩展,即当数据库中的数据归档为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);

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.%Property% = 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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梅窗月明清似水 2024-11-24 10:20:25

只需使用 Dapper。如果这对 SO 有好处,那对你也有好处;-)

Just use Dapper. If it's good for SO, it will be good for you, too ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文