Пример #1
0
        /// <summary>
        /// 获取是否支持数据类型。
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsDbTypeSupported(this Type type)
        {
            Guard.ArgumentNull(type, "type");
            type = type.GetNonNullableType();
            var typeCode = Type.GetTypeCode(type);

            if (ConvertManager.CanConvert(type))
            {
                return(true);
            }

            return(typeCode != TypeCode.Object &&
                   typeCode != TypeCode.Empty &&
                   typeCode != TypeCode.DBNull);
        }
Пример #2
0
        protected override Expression VisitColumn(ColumnExpression column)
        {
            if (_scope != null && _scope.TryGetValue(column, out ParameterExpression recordWrapper, out ParameterExpression dataReader, out int ordinal))
            {
                if (!column.Type.IsDbTypeSupported())
                {
                    throw new InvalidCastException(SR.GetString(SRKind.InvalidCastPropertyValue, column.Type.FullName));
                }

                //把 ColumnExpression 换成 RecordWrapper.GetInt32(IDataReader, int) 这样的表达式
                var dbType = column.MapInfo != null && column.MapInfo.DataType != null ?
                             (DbType)column.MapInfo.DataType : column.Type.GetDbType();

                var        method     = RecordWrapHelper.GetMethodByOrdinal(dbType);
                Expression expression = Expression.Call(recordWrapper, method, dataReader, Expression.Constant(ordinal));

                //先找转换器
                if (ConvertManager.CanConvert(column.Type))
                {
                    //调用ConvertManager.GetConverter
                    var converter = Expression.Call(null, MethodCache.GetConverter, Expression.Constant(column.Type));

                    //调用 IValueConverter.ConvertFrom
                    expression = Expression.Convert(
                        Expression.Call(converter, MethodCache.ConvertFrom, expression, Expression.Constant(dbType)),
                        column.Type);
                }
                else
                {
                    if (column.Type.IsNullableType())
                    {
                        //调用 RecordWrapper.IsDbNull 判断值是否为空
                        expression = Expression.Condition(
                            Expression.Call(recordWrapper, MethodCache.IsDbNull, dataReader, Expression.Constant(ordinal)),
                            Expression.Convert(Expression.Constant(null), column.Type),
                            Expression.Convert(expression, column.Type));
                    }
                    else if (column.Type != method.ReturnType)
                    {
                        expression = Expression.Convert(expression, column.Type);
                    }
                }

                return(expression);
            }

            return(column);
        }
Пример #3
0
        private void CompileFunction(IDataReader reader)
        {
            var newExp  = Expression.New(typeof(T));
            var mapping = GetMapping(GetDataReaderFields(reader));

            var rowMapExp = Expression.Constant(RecordWrapper);
            var parExp    = Expression.Parameter(typeof(IDataRecord), "s");

            var bindings =
                mapping.Select(s =>
            {
                var dbType         = reader.GetFieldType(s.Index);
                var getValueMethod = Data.RecordWrapper.RecordWrapHelper.GetMethodByOrdinal(dbType.GetDbType());

                var expression = (Expression)Expression.Call(rowMapExp, getValueMethod, new Expression[] { parExp, Expression.Constant(s.Index) });

                if (ConvertManager.CanConvert(s.Info.PropertyType))
                {
                    var converter = Expression.Call(typeof(ConvertManager), nameof(ConvertManager.GetConverter), null, Expression.Constant(s.Info.PropertyType));
                    expression    = Expression.Call(converter, MethodCache.ConvertFrom, Expression.Convert(expression, typeof(object)), Expression.Constant(dbType.GetDbType()));
                    expression    = Expression.Convert(expression, s.Info.PropertyType);
                }
                else if (s.Info.PropertyType.IsNullableType())
                {
                    expression = Expression.Condition(
                        Expression.Call(parExp, MethodCache.IsDBNull, Expression.Constant(s.Index, typeof(int))),
                        Expression.Convert(Expression.Constant(null), s.Info.PropertyType),
                        Expression.Convert(expression, s.Info.PropertyType));
                }
                else if (dbType != s.Info.PropertyType)
                {
                    expression = Expression.Convert(expression, s.Info.PropertyType);
                }

                return(Expression.Bind(s.Info, expression));
            });

            var expr =
                Expression.Lambda <Func <IDataReader, T> >(
                    Expression.MemberInit(
                        newExp,
                        bindings.ToArray()),
                    parExp);

            _funcDataRecd = expr.Compile();
        }