gpt4 book ai didi

c# - 将SqlDataReader写入立即窗口c#

转载 作者:行者123 更新时间:2023-11-30 12:22:54 26 4
gpt4 key购买 nike

我正在尝试调试抛出错误的 SQL 响应:

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

这没有多大意义,因为对象没有任何 bool 值。

代码:

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

执行的SQL(我手动添加参数):

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

我在读取发生的地方放置了断点(connection.Query<Rate>(query, parameters)),然后在异常时启用中断,当它失败时跳到更深的堆栈到 TdsParser TryRun() (抛出异常的级别更高)

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.BulkCopySimpleResultSet bulkCopyHandler, System.Data.SqlClient.TdsParserStateObject stateObj, out bool dataReady) + 0x1ce1 bytes

此时我可以访问 dataStream这是 SqlDataReader

我正在寻找一种方法来直接从 SqlDataReader 中输出“原始”结果, 像

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

但对于 SqlDataReader .

编辑

根据评论中的要求

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:对于那些想知道原因是什么的人

语句实际上是通过额外的机制转换成这个的

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?

最佳答案

即时调试立即窗口时如何编写 SqlDataReader?

SqlDataReader 实现接口(interface) IDataReader .以下技巧适用于任何实现此接口(interface)的阅读器。与 (new System.IO.StreamReader(stream)).ReadToEnd() 一样,这些技术将消耗数据读取器的内容,因此它不再可用。

纯粹即时转储结果。

如果您没有时间准备并且需要立即查看阅读器的内容,您可以将数据阅读器加载到即时窗口中定义的 DataTable 中,它们会打印出 XML对于那张 table 。

首先,在即时窗口中键入以下命令定义三个运行时全局变量:

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

每个 session 执行一次。

接下来,如果代码已经开始读取表格列,您可以通过键入以下内容获取当前行的值:

_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 的内容作为 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();
}
}
}

(注意 - 获取表名的代码未经过全面测试。)

请注意,我使用的是 序列化结果值并格式化整体结果。如果愿意,您可以使用不同的序列化程序。

在 Debug模式下构建项目并将其复制到方便的位置,比如 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字符串供人工检查。

关于c# - 将SqlDataReader写入立即窗口c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38953677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com