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)); }
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)); } }
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)); } }
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)); } }
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); } }