【问题标题】:C# using MYSQL ExecuteScalar() type errorC# 使用 MYSQL ExecuteScalar() 类型错误
【发布时间】:2017-05-05 00:11:13
【问题描述】:

我正在使用 Xamarin 中的 MySQL 库连接到我的数据库。我正在调用ExecuteScalar() 命令来检查我的数据库中是否存在用户。

我将 ExecuteScalar() 的返回值转换为 Int32 并存储在名为 userCount 的 Int32 变量中,但当我尝试调用 (int32)checkUser.ExecuteScalar(); 时,Visual Studio 会抛出 cast is not valid 错误

这就是documentation中建议的做法,所以我很困惑。这是我的代码:

using MySql.Data.MySqlClient;
using System.Data;

MySqlCommand checkUser = new MySqlCommand("SELECT COUNT(*) FROM <MyCoolDatabase> WHERE Userid = '" + username + "'", connection);

Int32 userCount = (Int32)checkUser.ExecuteScalar(); //error is here
if(userCount >0)
{
    //do stuff
}

【问题讨论】:

  • 您是否调试并看到 ExecuteScalar 返回的类型?
  • 听起来它返回了一个空值,这就是演员失败的原因
  • 你确定你没有返回 null 吗?顺便说一下,文档在这个链接dev.mysql.com/doc/connector-net/en/…
  • 感谢您的建议,如果我现在返回 null,我将进行测试
  • Int32 userCount = (int)(long)checkUser.ExecuteScalar();MySql下的Count返回一个Int64。

标签: c# mysql xamarin


【解决方案1】:

您链接到System.Data.SqlClient 而不是MySQL.Data.MySqlClient

https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-sql-command.html

那里有一个例子 -

object result = cmd.ExecuteScalar();
        if (result != null)
        {
            int r = Convert.ToInt32(result);
            Console.WriteLine("Number of countries in the world database is: " + r);
        }

您可能正在尝试将null 转换为int32

【讨论】:

  • 不,问题是结果是long,因为它被装箱在object 内,它不能直接转换为int32
  • SELECT Count(*) 将始终返回 long >= 0,绝不会返回 null,任何错误都会引发 Exception
  • Convert 在强制转换失败时不起作用除非输入是导致调用Int32.Parse()的字符串
  • @PanagiotisKanavos 我只是简单地从 MySql 文档中提供了此调用的文档。不知道为什么投反对票。
  • 这让我误以为“值太大或太小”。无法转换为 int32'
【解决方案2】:

几周前我遇到了同样的问题。 问题是 ExecuteScalar() 返回 long object 并且不能简单地转换为 int。但可以将其转换为 long,然后转换为 int

更改您的代码:

Int32 userCount = (Int32)checkUser.ExecuteScalar(); //error is here

收件人:

int userCount = (int)(long)(checkUser.ExecuteScalar());

这对我来说没有任何问题。


顺便说一句,如何使用参数有完整的解决方案:

using (MySqlCommand cmd = connection.CreateCommand())
{
    cmd.CommandText = "SELECT COUNT(*) FROM <MyCoolDatabase> WHERE Userid = @user";
    cmd.Parameters.AddWithValue("@user", username);

    int userCount = (int)(long)(checkUser.ExecuteScalar());
    if (userCount > 0)
    {
        //work
    }
}

【讨论】:

  • 当然可以! ExecuteScalarany 结果 wrapped 作为对象返回,您可以将其转换为适当的类型。如果您遇到问题,那是因为返回类型不是int。如果您尝试转换为long,您可能不会有任何问题。很容易找到正确的类型 - 只需在调试器中检查结果的内容
  • 换一种说法——自从 .NET 1.0 出现以来,人们总是投出ExecuteScalar() 的结果。如果需要转换为字符串,这 15 年就会有人注意到了。
  • 但你绝对不能只写(int)ExecuteScalar() 正如你所说的,你必须先转换为long,然后再转换为int。我已经更新了答案。
  • 没有。如果类型是 int,则需要强制转换为 int。如果它很长,则需要转换为 long 并使用该 long。如果类型很长,为什么你认为你可以安全地转换为 int 而不会抛出?或者您可以解析等效的字符串?如果数字超过最大 int 怎么办?
  • 如果数字是 5 或大于 Int32.max 并且有问题的@Barney Chambers 想要将结果存储在 int 变量中,那么 Mysql 计数的结果是长期独立的,这就是为什么另一个转换为 int 的原因。另一件事是这个查询应该总是只有 0 或 1,所以你不必担心限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多