zoukankan      html  css  js  c++  java
  • DataReaderGetterGenerator

    using System;
    using System.Text;
    using System.Data;
    using System.Reflection;
    using System.Reflection.Emit;
    using System.Collections.Generic;
    using System.CodeDom.Compiler;
    using Rocky;
    
    namespace System.Reflection.Emit
    {
        /// <summary>
        /// DataReaderGetterGenerator
        /// </summary>
        public class DataReaderGetterGenerator
        {
            #region IMemberGetterGenerator Members
    
            public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue)
            {
                MethodInfo getMethod;
                bool mustBeUnBox = false;
    
                switch (Type.GetTypeCode(memberValue.LocalType))
                {
                    //从实测的效果来看,使用特定的函数将不会提高性能,反而性能会更低。
                    case TypeCode.Boolean:
                        getMethod = typeof(IDataRecord).GetMethod("GetBoolean");
                        break;
                    case TypeCode.Byte:
                        getMethod = typeof(IDataRecord).GetMethod("GetByte");
                        break;
                    case TypeCode.Char:
                        getMethod = typeof(IDataRecord).GetMethod("GetChar");
                        break;
                    case TypeCode.DateTime:
                        getMethod = typeof(IDataRecord).GetMethod("GetDateTime");
                        break;
                    case TypeCode.Decimal:
                        getMethod = typeof(IDataRecord).GetMethod("GetDecimal");
                        break;
                    //Teddy 2008-2-2: commented the lines below, because for some database, return data type of float or real could always be System.Single or System.Double
                    //case TypeCode.Double:
                    //    getMethod = typeof(IDataRecord).GetMethod("GetDouble");
                    //    break;
                    //case TypeCode.Single:
                    //    getMethod = typeof(IDataRecord).GetMethod("GetFloat");
                    //    break;
                    case TypeCode.Int16:
                        getMethod = typeof(IDataRecord).GetMethod("GetInt16");
                        break;
                    case TypeCode.Int32:
                        getMethod = typeof(IDataRecord).GetMethod("GetInt32");
                        break;
                    case TypeCode.Int64:
                        getMethod = typeof(IDataRecord).GetMethod("GetInt64");
                        break;
                    case TypeCode.String:
                        getMethod = typeof(IDataRecord).GetMethod("GetString");
                        break;
                    default:
                        getMethod = typeof(IDataRecord).GetMethod("GetValue");
                        mustBeUnBox = true;
                        break;
                }
                if (memberValue.LocalType == typeof(Guid))
                {
                    getMethod = typeof(IDataRecord).GetMethod("GetGuid");
                    mustBeUnBox = false;
                }
                generator.Ldarg(targetObject);
                generator.Load(memberName);
                generator.Call(typeof(IDataRecord).GetMethod("GetOrdinal"));
                LocalBuilder fieldOrdinalLoc = generator.DeclareLocal(typeof(int));
                generator.Stloc(fieldOrdinalLoc);
                generator.Ldarg(targetObject);
                generator.Ldloc(fieldOrdinalLoc);
                generator.Call(typeof(IDataRecord).GetMethod("IsDBNull"));
                generator.IfNot();
                generator.Ldarg(targetObject);
                generator.Ldloc(fieldOrdinalLoc);
                generator.Call(getMethod);
    
                //Teddy 2008-2-2: added the  code section below to convert the object to the memberValue.LocalType
                if (getMethod == typeof(IDataRecord).GetMethod("GetValue"))
                {
                    generator.Load(Type.GetTypeCode(memberValue.LocalType));
                    generator.Call(typeof(Convert).GetMethod("ChangeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object), typeof(TypeCode) }, null));
                }
    
                if (memberValue.LocalType.IsValueType && mustBeUnBox)
                {
                    generator.UnboxAny(memberValue.LocalType);
                }
                generator.Else();
                generator.LoadDefaultValue(memberValue.LocalType);
                generator.EndIf();
                generator.Stloc(memberValue);
            }
    
            #endregion
    
            #region IMemberGetterGenerator Members
    
            public bool ContainsMember(string name, Type type, object inputObject)
            {
                //IDataReader.GetSchemaTable 得到的是以字段属性为列,字段为行的DataTable
                IDataReader dr = (IDataReader)inputObject;
                foreach (DataRow dataRow in dr.GetSchemaTable().Rows)
                {
                    if (dataRow.ItemArray[0].ToString() == name)
                    {
                        return true;
                    }
                }
                return false;
            }
    
            #endregion
        }
    }
  • 相关阅读:
    LeetCode:Symmetric Tree
    LeetCode:Construct Binary Tree from Inorder and Postorder Traversal,Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode:Binary Tree Level Order Traversal I II
    LeetCode:Binary Tree Zigzag Level Order Traversal
    LeetCode:Convert Sorted Array to Binary Search Tree,Convert Sorted List to Binary Search Tree
    LeetCode:Balanced Binary Tree
    LeetCode:Minimum Depth of Binary Tree,Maximum Depth of Binary Tree
    LeetCode:Path Sum I II
    LeetCode:Flatten Binary Tree to Linked List
    LeetCode:Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/Googler/p/2770343.html
Copyright © 2011-2022 走看看