c# - 如果使用 UNION ALL,MySqlDataReader 会为同一列返回不同的类型

标签 c# mysql

我有一个循环遍历从 MySqlCommand 生成的 DataReader,它的查询从一些字段中选择,包括 2 TINYINT(1)映射到 bool 的字段s 在 C# 上,这正是我所期望的。

当我将查询更改为执行 UNION ALL 时出现了问题同一张 table 。 更改查询后,我开始收到无效转换错误。 TINYINT(1)列现在返回 SByte s 而不是 Boolean .

这是 MySql 服务器的问题吗? MySql 网络/连接器问题?这是预期的行为吗?

示例查询:

string sql = @"SELECT tinyint1column FROM mytable WHERE id = 1";

command.CommandText = sql;

using(var reader = command.ExecuteReader())
{
    while(reader.Read())
    {
        bool flag = (bool)reader["tinyint1column"]; // OK - No error
    }
}

sql = @"SELECT tinyint1column FROM mytable WHERE id = 1
        UNION ALL
        SELECT tinyint1column FROM mytable WHERE id = 2";

command.CommandText = sql;

using(var reader = command.ExecuteReader())
{
    while(reader.Read())
    {
        bool flag = (bool)reader["tinyint1column"]; // Invalid cast error???
    }
}

在有人提问之前:

  • 我在共享主机上安装了 MySql Server 5.1,因此无法升级服务器。
  • 我使用的是 MySql.Data 版本 6.5.4,因为它是我唯一可以编译并以中等/部分推力在此共享主机上运行的版本。
  • 我实际上是在将读者“转换”到 List<DbDataRecord>.Cast<>()获取“断开连接的阅读器”的扩展方法,但它不会以任何方式更改基础数据。

最佳答案

我也可以通过 NET Connector 6.3 确认问题(?)。

然而,调用 reader.GetBoolean() 有一个简单的方法。
MySql 连接器中基本 IDbDataReader 的重写在读取器字段上内部调用 Convert.ToBoolean()

public bool GetBoolean(string name)
{
    return this.GetBoolean(this.GetOrdinal(name));
}

public override bool GetBoolean(int i)
{
    return Convert.ToBoolean(this.GetValue(i));
}

因此您可以轻松地调整您的代码以适应这种情况(并且它也适用于您的查询的单表版本)

using(var reader = command.ExecuteReader())
{
    while(reader.Read())
    {
        bool flag = reader.GetBoolean("tinyint1column"); 
        ....
    }
}

编辑 鉴于您在下方的评论,我认为您可以使用 DbDataRecord 类的扩展方法解决缺少 GetBoolean(fieldName) 的问题。
我已经使用 LinqPad 对此进行了测试,它似乎可以正常工作(如果该字段为 null,则返回内容的一部分)

public bool GetBoolean(DbDataRecord rec, string fieldName)
{
    int pos = rec.GetOrdinal(fieldName);
    if(rec.IsDBNull(pos))
        return false; // ??

    object result = rec.GetValue(pos);   
    return Convert.ToBoolean(result);
}

关于c# - 如果使用 UNION ALL,MySqlDataReader 会为同一列返回不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27808304/

相关文章:

c# - StreamReader 使用数组列表或数组

php - 如何在指定时间后自动从数据库中删除数据?

php - 如何在JPGRAPH中设置1秒后自动刷新

java - 如何让 Hibernate 在与 JPA 一起使用时自动在数据库中创建表?

c# - 我在说 "Assertion failed"之前从未见过的奇怪的 xCode 链接器错误

c# - 不破坏 html c# 的子字符串

c# - 将列表中的值分配给不包括空值的列表

c# - 生成后事件执行 PowerShell

MySQL - 两个值相除的 SELECT 返回不同的行数

php - 更新帖子不起作用