Write SqlDataReader to the nearest C # window

I am trying to debug an SQL response that causes an error:

Conversion error when converting varchar value '0.01' to data type bit.

This does not make much sense as the object does not have any bools.

the code:

 using (var connection = _connectionProvider.GetDbConnection())
 {
    connection.Open();
    return connection.Query<Rate>(query, parameters);
 }

SQL that is executing (I manually added parameters):

select * from (select top 1 BuildNumber, RateVersion, SampleId, Tariff, TariffStepName, Factor1, Result1 from dbo.Rates
where Tariff = 'Default' and TariffStepName = 'I_P' and (RateVersion <= 1) and Factor1 = 'false' and (SampleId is null)
order by RateVersion desc, sampleId desc) top1 

I set a breakpoint at the place where reading ( connection.Query<Rate>(query, parameters)) occurs , and then turned on the exception interrupt and when it fell deeper into the stack to TdsParser TryRun()(the level of the pair is higher where the exception is thrown)

System.Data.dll! System.Data.SqlClient.TdsParser.TryRun (System.Data.SqlClient.RunBehavior runBehavior, System.Data.SqlClient.SqlCommand cmdHandler, System.Data.SqlClient.SqlDataReader dataStream, System.Data. SqlClient.BulkCopySlimR bulk. SqlClient.TdsParserStateObject stateObj, out bool dataReady) + 0x1ce1 bytes

At this moment I have access to dataStreamwhich SqlDataReader

I'm looking for a way to output a raw result directly from SqlDataReader, something like

System.Diagnostics.Debug.WriteLine((new System.IO.StreamReader(stream)).ReadToEnd());

but for SqlDataReader.

EDIT

as per request in comment

public class Rate
{
    public string Tariff { get; set; }
    public string TariffStepName { get; set; }
    public string Factor1 { get; set; }
    public string Factor2 { get; set; }
    public string Factor3 { get; set; }
    public string Factor4 { get; set; }
    public string Factor5 { get; set; }
    public string Factor6 { get; set; }
    public string Factor7 { get; set; }
    public string Factor8 { get; set; }
    public string Factor9 { get; set; }
    public string Factor10 { get; set; }
    public decimal Result1 { get; set; }
    public decimal Result2 { get; set; }
    public decimal Result3 { get; set; }
    public decimal Result4 { get; set; }
    public decimal Result5 { get; set; }
    public decimal Result6 { get; set; }
    public decimal Result7 { get; set; }
    public decimal Result8 { get; set; }
    public decimal Result9 { get; set; }
    public decimal Result10 { get; set; }
    public string TextResult1 { get; set; }
    public string TextResult2 { get; set; }
    public string TextResult3 { get; set; }
    public string TextResult4 { get; set; }
    public string TextResult5 { get; set; }
    public int? SampleId { get; set; }
    public int BuildNumber { get; set; }
    public decimal? RateVersion { get; set; }
}

SQL

CREATE TABLE dbo.[Rates](
    [BuildNumber] [int] NOT NULL,
    [Tariff] [varchar](30) NOT NULL,
    [TariffStepName] [varchar](60) NOT NULL,
    [Factor1] [varchar](50) NOT NULL,
    [Factor2] [varchar](50) NULL,
    [Factor3] [varchar](50) NULL,
    [Factor4] [varchar](50) NULL,
    [Factor5] [varchar](50) NULL,
    [Factor6] [varchar](50) NULL,
    [Factor7] [varchar](50) NULL,
    [Factor8] [varchar](50) NULL,
    [Factor9] [varchar](50) NULL,
    [Factor10] [varchar](50) NULL,
    [Result1] [varchar](50) NULL,
    [Result2] [decimal](19, 6) NULL,
    [Result3] [decimal](19, 6) NULL,
    [Result4] [decimal](19, 6) NULL,
    [Result5] [decimal](19, 6) NULL,
    [Result6] [decimal](19, 6) NULL,
    [Result7] [decimal](19, 6) NULL,
    [Result8] [decimal](19, 6) NULL,
    [Result9] [decimal](19, 6) NULL,
    [Result10] [decimal](19, 6) NULL,
    [RateVersion] [decimal](18, 2) NULL,
    [SampleId] [int] NULL,
    [TextResult1] [varchar](50) NULL,
    [TextResult2] [varchar](50) NULL,
    [TextResult3] [varchar](50) NULL,
    [TextResult4] [varchar](50) NULL,
    [TextResult5] [varchar](50) NULL
)

EDIT2: For those who are wondering what is the reason

Operation

was actually transformed into it by an additional mechanism

exec sp_executesql N'select * from (select top 1 BuildNumber, RateVersion, SampleId, Tariff, TariffStepName, Factor1, Result1 from dbo.Rates
where Tariff = @Tariff and TariffStepName = @TariffStepName and (RateVersion <= @RV) and Factor1 = @Factor1 and (SampleId is null)
order by RateVersion desc, sampleId desc) top1 
',N'@Tariff varchar(50),@TariffStepName varchar(50),@RV decimal(3,2),@Factor1 bit',@Tariff='Default',@TariffStepName='I_P',@RV=1.00,@Factor1=0
go

, , top 1, ,

- : SqlDataReader " " ?

+4
3

SqlDataReader " " ?

SqlDataReader IDataReader. , . (new System.IO.StreamReader(stream)).ReadToEnd(), , .

.

, DataTable, , XML .

, :

object [] _objs = null;
DataTable _table = null;
DataSet _set = null;

.

, , , :

_objs = new object[dataStream.FieldCount];
dataStream.GetValues(_objs);
_objs

.

, , :

_table = new DataTable();
_table.Load(dataStream);
_set = new DataSet();
_set.Tables.Add(_table);
_set.GetXml();
Debug.WriteLine(_set.GetXml());

_set, Immediate XML-. , , DataTable.Load(IDataReader) , .

, , , , .

.

, .

DLL , , , . , .

namespace DataReaderDebugUtilities
{
    public static class DataReaderExtensions
    {
        public static object[] CurrentValues(this IDataReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException();
            var objs = new object[reader.FieldCount];
            reader.GetValues(objs);
            return objs;
        }

        public static KeyValuePair<string, object> [] CurrentNamesAndValues(this IDataReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException();
            var query = Enumerable.Range(0, reader.FieldCount).Select(i => new KeyValuePair<string, object>(reader.GetName(i), reader.GetValue(i)));
            return query.ToArray();
        }

        public static string ToStringAsDataTable(this IDataReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException();
            var sb = new StringBuilder();
            using (var textWriter = new StringWriter(sb))
            using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.Indented })
            {
                var serializer = JsonSerializer.CreateDefault();
                jsonWriter.WriteDataTable(reader, serializer);
            }
            return sb.ToString();
        }

        public static string ToStringAsDataSet(this IDataReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException();
            var sb = new StringBuilder();
            using (var textWriter = new StringWriter(sb))
            using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.Indented })
            {
                var serializer = JsonSerializer.CreateDefault();
                jsonWriter.WriteDataSet(reader, serializer);
            }
            return sb.ToString();
        }
    }

    public static class JsonExtensions
    {
        public static void WriteDataTable(this JsonWriter writer, IDataReader reader, JsonSerializer serializer)
        {
            if (writer == null || reader == null || serializer == null)
                throw new ArgumentNullException();
            writer.WriteStartArray();
            while (reader.Read())
            {
                writer.WriteStartObject();
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    writer.WritePropertyName(reader.GetName(i));
                    serializer.Serialize(writer, reader[i]);
                }
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
        }

        public static void WriteDataSet(this JsonWriter writer, IDataReader reader, JsonSerializer serializer)
        {
            if (writer == null || reader == null || serializer == null)
                throw new ArgumentNullException();
            writer.WriteStartObject();

            do
            {
                var tableName = string.Empty;
                var schemaTable = reader.GetSchemaTable();
                if (schemaTable != null)
                    tableName = schemaTable.Rows.Cast<DataRow>()
                        .Select(r => r[schemaTable.Columns[System.Data.Common.SchemaTableColumn.BaseTableName]].ToString())
                        .FirstOrDefault();
                writer.WritePropertyName(tableName ?? string.Empty);
                writer.WriteDataTable(reader, serializer);
            }
            while (reader.NextResult());

            writer.WriteEndObject();
        }
    }
}

(. .)

. . , .

, C:\Temp\DataReaderDebugUtilities.dll.

, , :

Assembly.LoadFile(@"C:\Temp\DataReaderDebugUtilities.dll");

DLL , . , :

DataReaderDebugUtilities.DataReaderExtensions.CurrentNamesAndValues(dataStream)

, .

string _s = DataReaderDebugUtilities.DataReaderExtensions.ToStringAsDataSet(dataStream);

string _s = DataReaderDebugUtilities.DataReaderExtensions.ToStringAsDataTable(dataStream);

JSON .

+2
  • Dapper - Open Source.
  • 1 varchar (50), # .
0

Conversion failed when converting the varchar value '0.01' to data type bit.
, SQL. SQL . SQL SSMS.

0
source

Source: https://habr.com/ru/post/1651277/


All Articles