MySQL C# - 如何从 MySQL 中检索枚举类型

MySQL C# - How to retrieve enum type from MySQL

提问人:spoooooooonman 提问时间:8/1/2023 更新时间:8/1/2023 访问量:72

问:

我有一个名为ProfileType的枚举,在MySQL中它存储为一个枚举,如下所示:

问题是,一旦我尝试登录,它就会崩溃,给我一个“指定的演员表无效”,这在启动配置文件时会发生。

var cmd = new MySqlCommand($"select * from users where username='{username}' and password='{password}'", connection);
        var rd = cmd.ExecuteReader();
        if (rd.HasRows)
        {
            rd.Read();
            return new Profile
            {
                Username = rd.GetString("username"),
                Email = rd.GetString("email"),
                Password = rd.GetString("password"),
                Picture = rd.GetString("picture"),
                ProfileType = (ProfileType)rd.GetInt16("profileType"),
                AdditionalData = rd.GetString("additionalData")
            };

这是枚举:

public enum ProfileType
{
    User = 0,
    Library = 1,
    Admin = 2
}

我使用 int 来存储枚举,但即使我注册为库,它也总是给我“0”。

C# MySQL 枚举强制 转换

评论

1赞 Charlieface 8/1/2023
返回什么类型?SIde 指出:你有危险的 SQL 注入,你应该改用参数。此外,您还需要用 .我真诚地希望您不要存储纯文本密码。另外,为什么要从数据库中带回密码,这似乎是另一个被恶意读取的机会?rd.GetFieldType("profileType")using
0赞 spoooooooonman 8/1/2023
@Charlieface是的,我知道这一点,但我正在努力让一切首先发挥作用。路。GetFieldType(“profileType”) 返回一个 System.Type,我无法将其强制转换为 ProfileType
0赞 Charlieface 8/1/2023
是的,这就是它应该返回的,只是一个类型对象而不是实际数据,那个类型是什么rd.GetFieldType("profileType").ToString()
0赞 spoooooooonman 8/1/2023
它只是返回“System.String”,我不知道你让我做什么对不起。我需要检查什么类型?

答:

-1赞 rotabor 8/1/2023 #1

由于“rd.GetFieldType(“配置文件类型”)。ToString()“是”System.String“,则无法从中获取 GetInt16。

ProfileType = (ProfileType)rd.GetInt16("profileType")

-->

ProfileType = Enum.Parse<ProfileType>(rd.GetString("profileType"))
4赞 Charlieface 8/1/2023 #2

MySQL枚举类型实际上是以字符串形式返回的,因此您需要解析它

ProfileType = Enum.Parse<ProfileType>(rd.GetString("profileType")),

或在旧版本的 .NET 上

ProfileType = (ProfileType)Enum.Parse(typeof(ProfileType), rd.GetString("profileType")),

关于代码的旁注:

  • 你有危险的SQL注入,你应该改用参数。
  • 您需要用 .using
  • 我真诚地希望您不要存储纯文本密码。你应该对它们进行盐和散列处理。
  • 为什么要从数据库中取回密码,这似乎是另一个被恶意读取的机会?
  • if (rd.HasRows)是不必要的,你可以从中得到rd.Read()
using var cmd = new MySqlCommand(@"
select
  username,
  email,
  picture,
  profileType,
  additionalData
from users
where username = @username
  and passwordHash = @passwordHash;
", connection);
cmd.Parameters.AddWithValue("@username", username);
cmd.Parameters.AddWithValue("@passwordHash", SaltAndHash(password, username));

using var rd = cmd.ExecuteReader();
if(rd.Read())
    return new Profile
    {
        Username = rd.GetString("username"),
        Email = rd.GetString("email"),
        Picture = rd.GetString("picture"),
        ProfileType = Enum.Parse<ProfileType>(rd.GetString("profileType")),
        AdditionalData = rd.GetString("additionalData")
    };

评论

0赞 Charlieface 8/1/2023
您使用的是哪个版本的 .NET?
0赞 spoooooooonman 8/1/2023
我在 4.0 上。只是需要更新?
0赞 Charlieface 8/1/2023
请参阅编辑,您可以采用铸造的旧方法。更新到 4.x 之后是一项重大更改(对 .NET Core),因此取决于您还有什么。如果您使用的是 WinForms 或第三方库,那么您可能会破坏一些东西。
0赞 spoooooooonman 8/1/2023
在告诉你之前,我试过这个,但不幸的是,它没有解决任何问题。同样的错误
0赞 Charlieface 8/1/2023
(ProfileType)Enum.Parse(typeof(ProfileType), rd.GetString("profileType"))不使用任何泛型,怎么会是同样的错误?