Example #1
0
        public Expression Reduce(IDataContext dataContext, bool slowMode)
        {
            var columnReader = new ColumnReader(dataContext, dataContext.MappingSchema, _type, _idx, Converter, slowMode);

            if (slowMode && Configuration.OptimizeForSequentialAccess)
            {
                return(Convert(Call(Constant(columnReader), Methods.LinqToDB.ColumnReader.GetValueSequential, _dataReaderParam, Call(_dataReaderParam, Methods.ADONet.IsDBNull, ExpressionInstances.Int32Array(_idx)), Call(Methods.LinqToDB.ColumnReader.RawValuePlaceholder)), _type));
            }
            else
            {
                return(Convert(Call(Constant(columnReader), Methods.LinqToDB.ColumnReader.GetValue, _dataReaderParam), _type));
            }
        }
Example #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);
        }
Example #3
0
        private void Path <T>(IEnumerable <T> source, PropertyInfo property)
            where T : Expression
        {
            var prop = Expression.Property(_path, property);
            var i    = 0;

            foreach (var item in source)
            {
                _path = Expression.Call(prop, ReflectionHelper.IndexExpressor <T> .Item, ExpressionInstances.Int32Array(i++));
                Path(item);
            }
        }