异常: 指定的转换无效。

5
public class UserLoginInfo
{
    public UserRole Role;
    public string Username;

    public static UserLoginInfo FetchUser(string username, string password)
    {
        using (var connection = Utils.Database.GetConnection())
        using (var command = new SqlCommand("SELECT [Username], [Password], [Role] FROM [Users] WHERE [Username] = @username", connection))
        {
            command.Parameters.AddWithValue("@username", username);
            using (var reader = command.ExecuteReader())
            {
                if (reader == null || !reader.Read() || !Utils.Hash.CheckPassword(username, password, (byte[])reader["Password"]))
                    throw new Exception("Wrong username or password.");

                return new UserLoginInfo { Username = (string)reader["Username"], Role = (UserRole)reader["Role"] };
            }
        }
    }
}

当我设置断点并调试时,错误来自这一行。
return 
    new UserLoginInfo 
    { 
        Username = (string)reader["Username"], 
        Role = (UserRole)reader["Role"] 
    };

我不明白为什么会出现这个错误,请帮帮我!

编辑:如何将(字符串)reader["Role"]转换为UserRole?

public enum UserRole
{
    Admin,
    Maintance,
    User
}

你对UserRole进行了转换,那么Username也需要转换吗? - DOK
请查看我的更新答案,了解如何转换为您的枚举值。 - Winston Smith
1
顺便问一下,为什么你的 RoleUsername 成员是公共的?你至少应该使用 public UserRole Role { get; set; } 将它们转换为自动属性。 - Daniel Pryden
6个回答

10
Role = (UserRole)reader["Role"]

假设 UserRole 是您定义的一种类型,因此 SqlDataReader 不知道如何将从数据库获取的数据转换为此类型。那么,请问该列在您的数据库中是什么类型?

编辑:至于您更新后的问题,您可以执行以下操作:

var role = (string)reader["Role"];
UserRole role = (UserRole)Enum.Parse( typeof(UserRole), role );

你可能需要添加一些额外的错误检查,例如检查 role 不为 null。 此外,在解析枚举之前,您可以使用Enum.IsDefined 检查解析是否有效。


2

(UserRole)reader["Role"] 应为 (string)reader["Role"]。在 SQL Server 中没有 UserRole 类型。


1

代码可能在以下位置出现故障:

Role = (UserRole)reader["Role"];

因为您正在尝试将一个 object 强制转换为一个 UserRole,而这种类型的转换是不存在的。

看起来您正在尝试将 reader["Role"] 转换为一个 UserRole 对象,我猜那就是失败的原因。

您需要指定(或实现)一个有效的转换,或实现类似于 UserRole.Parse(string value) 的方法来将字符串解析为有效的 UserRole 对象。


1
如果您在数据库中存储的是字符串(string),但您希望将其转换为枚举(enum)类型,则应使用Enum.Parse()方法
例如:
UserRole userRole = (UserRole) Enum.Parse(typeof(UserRole), (string) reader["Role"]);

0

可能 (UserRole)Enum.Parse(typeof(UserRole), (string) reader["Role"]) 是最受欢迎的答案,而且令我惊讶的是,它还真的有效!(令人惊讶的是,即使是整数的字符串表示形式,Enum.Parse 方法也能正确地将其转换为相应的枚举值,考虑到数据库中的枚举值存储为整数)。但这正是我经常做的事情,言简意赅:

UserRole role = (UserRole)Convert.ToInt32(reader["Role"]);

尽管在现实生活中没有明显的改变,但这应该更加有效率。


0
这意味着你要么不能将`(string)reader["Username"]`进行转换(不太可能),要么不能将`(UserRole)reader["Role"]`进行转换(更有可能)。那么`UserRole`是什么 - 你能通过从数据库结果进行转换来创建它吗?难道你不需要像`new UserRole(reader["Role"])`这样的东西吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接