Esempio n. 1
0
            public T ReMapOnException(IDataContext context, IQueryRunner queryRunner, DbDataReader dataReader, ref ReaderMapperInfo mapperInfo, Exception ex)
            {
                if (context.GetTraceSwitch().TraceInfo)
                {
                    context.WriteTraceLine(
                        $"Mapper has switched to slow mode. Mapping exception: {ex.Message}",
                        context.GetTraceSwitch().DisplayName,
                        TraceLevel.Error);
                }

                queryRunner.MapperExpression = mapperInfo.MapperExpression;

                var dataReaderType = dataReader.GetType();
                var expression     = TransformMapperExpression(context, dataReader, dataReaderType, true);
                var expr           = mapperInfo.MapperExpression;                 // create new instance to avoid race conditions without locks

                mapperInfo = new ReaderMapperInfo()
                {
                    MapperExpression = expr,
                    Mapper           = expression.CompileExpression(),
                    IsFaulted        = true
                };

                _mappers[dataReaderType] = mapperInfo;

                return(mapperInfo.Mapper(queryRunner, dataReader));
            }
Esempio n. 2
0
            public T Map(IDataContext context, IQueryRunner queryRunner, IDataReader dataReader)
            {
                var dataReaderType = dataReader.GetType();

                if (!_mappers.TryGetValue(dataReaderType, out var mapperInfo))
                {
                    var mapperExpression = TransformMapperExpression(context, dataReader, dataReaderType, false);

                    var qr = QueryRunner;
                    if (qr != null)
                    {
                        qr.MapperExpression = mapperExpression;
                    }

                    var mapper = mapperExpression.Compile();
                    mapperInfo = new ReaderMapperInfo()
                    {
                        MapperExpression = mapperExpression, Mapper = mapper
                    };
                    _mappers.TryAdd(dataReaderType, mapperInfo);
                }

                try
                {
                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
                // SqlNullValueException: MySqlData
                // OracleNullValueException: managed and native oracle providers
                catch (Exception ex) when(ex is FormatException || ex is InvalidCastException || ex is LinqToDBConvertException || ex.GetType().Name.Contains("NullValueException"))
                {
                    // TODO: debug cases when our tests go into slow-mode (e.g. sqlite.ms)
                    if (mapperInfo.IsFaulted)
                    {
                        throw;
                    }

                    if (context.GetTraceSwitch().TraceInfo)
                    {
                        context.WriteTraceLine(
                            $"Mapper has switched to slow mode. Mapping exception: {ex.Message}",
                            context.GetTraceSwitch().DisplayName,
                            TraceLevel.Error);
                    }

                    var qr = QueryRunner;

                    if (qr != null)
                    {
                        qr.MapperExpression = mapperInfo.MapperExpression;
                    }

                    var expression = TransformMapperExpression(context, dataReader, dataReaderType, true);

                    mapperInfo.Mapper = expression.Compile();

                    mapperInfo.IsFaulted = true;

                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
            }
Esempio n. 3
0
            public T Map(IDataContext context, IQueryRunner queryRunner, DbDataReader dataReader, ref ReaderMapperInfo mapperInfo)
            {
                try
                {
                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
                // SqlNullValueException: MySqlData
                // OracleNullValueException: managed and native oracle providers
                catch (Exception ex) when(ex is FormatException or InvalidCastException or LinqToDBConvertException || ex.GetType().Name.Contains("NullValueException"))
                {
                    // TODO: debug cases when our tests go into slow-mode (e.g. sqlite.ms)
                    if (mapperInfo.IsFaulted)
                    {
                        throw;
                    }

                    return(ReMapOnException(context, queryRunner, dataReader, ref mapperInfo, ex));
                }
            }
Esempio n. 4
0
            public T Map(IDataContext context, IQueryRunner queryRunner, IDataReader dataReader)
            {
                // unwrap early
                // https://github.com/linq2db/linq2db/issues/2499
                dataReader = DataReaderWrapCache.TryUnwrapDataReader(context.MappingSchema, dataReader);

                var dataReaderType = dataReader.GetType();

                if (!_mappers.TryGetValue(dataReaderType, out var mapperInfo))
                {
                    var mapperExpression = TransformMapperExpression(context, dataReader, dataReaderType, false);

                    queryRunner.MapperExpression = mapperExpression;

                    var mapper = mapperExpression.CompileExpression();
                    mapperInfo = new ReaderMapperInfo()
                    {
                        MapperExpression = mapperExpression, Mapper = mapper
                    };
                    _mappers.TryAdd(dataReaderType, mapperInfo);
                }

                try
                {
                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
                // SqlNullValueException: MySqlData
                // OracleNullValueException: managed and native oracle providers
                catch (Exception ex) when(ex is FormatException || ex is InvalidCastException || ex is LinqToDBConvertException || ex.GetType().Name.Contains("NullValueException"))
                {
                    // TODO: debug cases when our tests go into slow-mode (e.g. sqlite.ms)
                    if (mapperInfo.IsFaulted)
                    {
                        throw;
                    }

                    if (context.GetTraceSwitch().TraceInfo)
                    {
                        context.WriteTraceLine(
                            $"Mapper has switched to slow mode. Mapping exception: {ex.Message}",
                            context.GetTraceSwitch().DisplayName,
                            TraceLevel.Error);
                    }

                    queryRunner.MapperExpression = mapperInfo.MapperExpression;

                    var expression = TransformMapperExpression(context, dataReader, dataReaderType, true);

                    // create new instance to avoid race conditions without locks
                    var expr = mapperInfo.MapperExpression;

                    mapperInfo = new ReaderMapperInfo()
                    {
                        MapperExpression = expr,
                        Mapper           = expression.CompileExpression(),
                        IsFaulted        = true
                    };

                    _mappers[dataReaderType] = mapperInfo;

                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
            }
Esempio n. 5
0
            public T Map(IDataContext context, IQueryRunner queryRunner, IDataReader dataReader)
            {
                var dataReaderType = dataReader.GetType();

                ParameterExpression?oldVariable;
                ParameterExpression?newVariable;
                LambdaExpression?   converterExpr;
                Type variableType;

                if (!_mappers.TryGetValue(dataReaderType, out var mapperInfo))
                {
                    converterExpr = context.MappingSchema.GetConvertExpression(dataReaderType, typeof(IDataReader), false, false);
                    variableType  = converterExpr != null ? context.DataReaderType : dataReaderType;

                    oldVariable = null;
                    newVariable = null;
                    var mapperExpression = (Expression <Func <IQueryRunner, IDataReader, T> >)_expression.Transform(
                        e => {
                        if (e is ConvertFromDataReaderExpression ex)
                        {
                            return(ex.Reduce(context, dataReader, newVariable !).Transform(replaceVariable));
                        }

                        return(replaceVariable(e));
                    });

                    var qr = QueryRunner;
                    if (qr != null)
                    {
                        qr.MapperExpression = mapperExpression;
                    }

                    var mapper = mapperExpression.Compile();
                    mapperInfo = new ReaderMapperInfo()
                    {
                        MapperExpression = mapperExpression, Mapper = mapper
                    };
                    _mappers.TryAdd(dataReaderType, mapperInfo);
                }

                try
                {
                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }
                catch (Exception ex) when(ex is FormatException || ex is InvalidCastException || ex is LinqToDBConvertException)
                {
                    // TODO: debug cases when our tests go into slow-mode (e.g. sqlite.ms)
                    if (mapperInfo.IsFaulted)
                    {
                        throw;
                    }

                    if (context.GetTraceSwitch().TraceInfo)
                    {
                        context.WriteTraceLine(
                            $"Mapper has switched to slow mode. Mapping exception: {ex.Message}",
                            context.GetTraceSwitch().DisplayName,
                            TraceLevel.Error);
                    }

                    var qr = QueryRunner;

                    if (qr != null)
                    {
                        qr.MapperExpression = mapperInfo.MapperExpression;
                    }

                    converterExpr = context.MappingSchema.GetConvertExpression(dataReaderType, typeof(IDataReader), false, false);
                    variableType  = converterExpr != null ? context.DataReaderType : dataReaderType;

                    oldVariable = null;
                    newVariable = null;
                    var expression = (Expression <Func <IQueryRunner, IDataReader, T> >)_expression.Transform(e => {
                        if (e is ConvertFromDataReaderExpression ex)
                        {
                            return(new ConvertFromDataReaderExpression(ex.Type, ex.Index, newVariable !, context));
                        }

                        return(replaceVariable(e));
                    });

                    mapperInfo.Mapper = expression.Compile();

                    mapperInfo.IsFaulted = true;

                    return(mapperInfo.Mapper(queryRunner, dataReader));
                }

                Expression replaceVariable(Expression e)
                {
                    if (e is ParameterExpression vex && vex.Name == "ldr")
                    {
                        oldVariable = vex;
                        return(newVariable ?? (newVariable = Expression.Variable(variableType, "ldr")));
                    }

                    if (e is BinaryExpression bex &&
                        bex.NodeType == ExpressionType.Assign &&
                        bex.Left == oldVariable)
                    {
                        Expression dataReaderExpression = Expression.Convert(_expression.Parameters[1], dataReaderType);

                        if (converterExpr != null)
                        {
                            dataReaderExpression = Expression.Convert(converterExpr.GetBody(dataReaderExpression), variableType);
                        }

                        return(Expression.Assign(newVariable, dataReaderExpression));
                    }

                    return(e);
                }
            }