示例#1
0
        private static Func <IDataRecord, o> getReaderConverter <o>(IDataRecord record)
        {
            Type typeIn  = typeof(IDataRecord);
            Type typeOut = typeof(o);

            Delegate creator = null;

            if (!_expressionReaderCache.TryGetValue(typeOut, out creator))
            {
                List <Expression> statements = new List <Expression>();

                ParameterExpression peIn  = Expression.Variable(typeIn);
                ParameterExpression peOut = Expression.Variable(typeOut);

                statements.Add(Expression.Assign(peOut, Expression.New(typeOut)));

                Type             customAttrMapper      = typeof(System.Data.Linq.Mapping.ColumnAttribute);
                BinaryExpression beAssignProp          = null;
                System.Reflection.PropertyInfo[] props = typeOut.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                foreach (System.Reflection.PropertyInfo piOut in props)
                {
                    int columnIndex = -1;

                    try
                    {
                        //find column index
                        System.Data.Linq.Mapping.ColumnAttribute[] attrs = (System.Data.Linq.Mapping.ColumnAttribute[])piOut.GetCustomAttributes(customAttrMapper, false);

                        if (attrs.Length > 0)
                        {
                            columnIndex = record.GetOrdinal(attrs[0].Name);
                        }
                        else
                        {
                            columnIndex = record.GetOrdinal(piOut.Name);
                        }
                    }
                    catch (IndexOutOfRangeException iorEx)
                    {
                        //skip if not match to any column
                        continue;
                    }

                    ConstantExpression   ce    = Expression.Constant(columnIndex, typeof(int));
                    MethodCallExpression mce   = null;
                    MemberExpression     meOut = Expression.Property(peOut, piOut.Name);

                    if (piOut.PropertyType.IsGenericType)
                    {
                        mce = Expression.Call(peIn, typeIn.GetMethod("Get" + Nullable.GetUnderlyingType(piOut.PropertyType).Name), new Expression[] { ce });

                        beAssignProp = BinaryExpression.Assign(meOut, Expression.Convert(mce, piOut.PropertyType));
                    }
                    else
                    {
                        mce = Expression.Call(peIn, typeIn.GetMethod("Get" + piOut.PropertyType.Name), new Expression[] { ce });

                        beAssignProp = BinaryExpression.Assign(meOut, mce);
                    }

                    MethodCallExpression  mceCheck = Expression.Call(peIn, typeIn.GetMethod("IsDBNull"), new Expression[] { ce });
                    ConditionalExpression conde    = Expression.IfThen(Expression.Not(mceCheck), beAssignProp);

                    //statements.Add(beAssignProp);
                    statements.Add(conde);
                }

                var returnStatement = peOut;
                statements.Add(returnStatement);

                var body = Expression.Block(new[] { peOut }, statements.ToArray());

                var lamda = Expression.Lambda <Func <IDataRecord, o> >(body, peIn);
                creator = lamda.Compile();

                _expressionReaderCache[typeOut] = creator;
            }

            return((Func <IDataRecord, o>)creator);
        }