【问题标题】:Specified cast is not valid when querying MySQL查询 MySQL 时指定的强制转换无效
【发布时间】:2017-04-06 20:31:37
【问题描述】:

通过 MySQL.Data.Entity v6.9.9(当前版本)连接到 MySQL 数据库。试图检索所有列表 通过直接 SQL 查询的表(在MyDBContext 内):

public async Task<IEnumerable<DBTableInfo>> GetTablesAsync()
{
    string sql = @"SELECT TABLE_NAME Name, TABLE_ROWS NumRows 
        FROM information_schema.tables
        where TABLE_TYPE='BASE TABLE'
        order by TABLE_NAME;";
    var result = Database.SqlQuery<DBTableInfo>(sql);
    return await result.ToListAsync();
}

DBTableInfo 简单定义为:

public class DBTableInfo
{
    public string Name { get; set; }
    public long NumRows { get; set; }
}

我收到错误:

指定的转换无效。

违规行是GetTableAsync 方法的return 语句。发生错误是因为 DBTableInfoNumRows 属性。如果我从DBTableInfo 中注释掉NumRows 属性,则查询有效。

现在,information_schema.tablesTABLE_ROWS 定义为 bigint。我的DBTableInfo 对象 将相应的属性声明为long。即使此列不包含空值,我也尝试使用long?, 它也不起作用。

为什么?任何有关处理它的最佳方法的建议将不胜感激。

【问题讨论】:

  • 如果您将 NumRows 属性更改为 object 而不是 long,您可以检查实际用于反序列化 TABLE_ROWS 值的类型。你试过检查吗?
  • @Mt. Schneiders 它以 null 的形式返回。
  • 你试过使用十进制作为数据类型吗?
  • @Mt. Schneiders 实际上,它似乎以System.UInt64 的形式回归,也就是ulong。但是我得到的所有表的值都为零,即使是那些不为空的表。不,decimal 也不起作用。
  • 假设查询正确,您可以尝试将列值转换为 SQL 查询本身。

标签: c# mysql


【解决方案1】:

通过将NumRows 值转换为 SQL 中的签名版本,问题得到解决(更像是“解决”,如下所示:

CAST(TABLE_ROWS as SIGNED) NumRows

确保我的班级仍被定义为:

public class DBTableInfo
{
    public string Name { get; set; }
    public long NumRows { get; set; } // <-- ulong does not work!
}

通过这两个步骤,记录可以正确反序列化。

请注意,您不能使用 ulong(无符号 64 位整数)作为 NumRows 的声明类型,因为 - 事实证明 - 实体框架仍然不支持无符号长整数。我花了一段时间才重新学习这一点。

这是一个相关的参考:

How to use unsigned int / long types with Entity Framework?

因此,您必须将数据库中的 unsigned long 值转换为签名版本,将类的接收成员声明为(已签名)@987654327 @。

不幸的是,这为 MySQL 端的溢出错误留下了空间。幸运的是,我的表远不及会成为真正问题的行数。

【讨论】:

    猜你喜欢
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    相关资源
    最近更新 更多