コード例 #1
0
        static Expression ConvertExpressionToType(Expression current, Type toType, MappingSchema mappingSchema)
        {
            var toConvertExpression = mappingSchema.GetConvertExpression(current.Type, toType, false, current.Type != toType);

            if (toConvertExpression == null)
            {
                return(current);
            }

            current = InternalExtensions.ApplyLambdaToExpression(toConvertExpression, current);

            return(current);
        }
コード例 #2
0
        static Expression GetColumnReader(
            IDataContext dataContext, MappingSchema mappingSchema, IDataReader dataReader, Type type, IValueConverter?converter, int idx, Expression dataReaderExpr, bool forceNullCheck)
        {
            var toType = type.ToNullableUnderlying();

            Expression ex;

            if (converter != null)
            {
                var expectedProvType = converter.FromProviderExpression.Parameters[0].Type;
                ex = dataContext.GetReaderExpression(dataReader, idx, dataReaderExpr, expectedProvType);
            }
            else
            {
                ex = dataContext.GetReaderExpression(dataReader, idx, dataReaderExpr, toType);
            }

            if (ex.NodeType == ExpressionType.Lambda)
            {
                var l = (LambdaExpression)ex;

                switch (l.Parameters.Count)
                {
                case 1: ex = l.GetBody(dataReaderExpr);                                 break;

                case 2: ex = l.GetBody(dataReaderExpr, ExpressionInstances.Int32(idx)); break;
                }
            }

            if (converter != null)
            {
                // we have to prepare read expression to conversion
                //
                var expectedType = converter.FromProviderExpression.Parameters[0].Type;

                if (converter.HandlesNulls)
                {
                    ex = Condition(
                        Call(dataReaderExpr, Methods.ADONet.IsDBNull, ExpressionInstances.Int32Array(idx)),
                        Constant(mappingSchema.GetDefaultValue(expectedType), expectedType),
                        ex);
                }

                if (expectedType != ex.Type)
                {
                    ex = ConvertExpressionToType(ex, expectedType, mappingSchema);
                }

                ex = InternalExtensions.ApplyLambdaToExpression(converter.FromProviderExpression, ex);
                if (toType != ex.Type && toType.IsAssignableFrom(ex.Type))
                {
                    ex = Convert(ex, toType);
                }
            }
            else if (toType.IsEnum)
            {
                var mapType = ConvertBuilder.GetDefaultMappingFromEnumType(mappingSchema, toType) !;

                if (mapType != ex.Type)
                {
                    // Use only defined convert
                    var econv = mappingSchema.GetConvertExpression(ex.Type, type, false, false) ??
                                mappingSchema.GetConvertExpression(ex.Type, mapType, false) !;

                    ex = InternalExtensions.ApplyLambdaToExpression(econv, ex);
                }
            }

            if (ex.Type != type)
            {
                ex = ConvertExpressionToType(ex, type, mappingSchema) !;
            }

            // Try to search postprocessing converter TType -> TType
            //
            ex = ConvertExpressionToType(ex, ex.Type, mappingSchema) !;

            // Add check null expression.
            // If converter handles nulls, do not provide IsNull check
            // Note: some providers may return wrong IsDBNullAllowed, so we enforce null check in slow mode. E.g.:
            // Microsoft.Data.SQLite
            // Oracle (group by columns)
            // MySql.Data and some other providers enforce null check in IsDBNullAllowed implementation
            if (converter?.HandlesNulls != true &&
                (forceNullCheck || (dataContext.IsDBNullAllowed(dataReader, idx) ?? true)))
            {
                ex = Condition(
                    Call(dataReaderExpr, Methods.ADONet.IsDBNull, ExpressionInstances.Int32Array(idx)),
                    Constant(mappingSchema.GetDefaultValue(type), type),
                    ex);
            }

            return(ex);
        }