InvalidCastException,从ASP中的SqlDataReader获取enum值.净MVC

本文关键字:enum MVC 获取 SqlDataReader ASP 中的 InvalidCastException | 更新日期: 2023-09-27 18:13:19

我在运行时使用此代码获得System.InvalidCastException:

inf.Country = (Country)(int)rdr["Country"];

模型类:

public class BasicInfo
{
    .....
    public Gender Gender { get; set; }
    public Country Country { get; set; }
}
public enum Gender
{
    Male,
    Female
}
public enum Country
{
    Australia,
    Bangladesh,
    England,
    France,
    Usa
}

DbConnect类:该方法返回实体列表,它将通过控制器的视图。

usp_GetAllStudentData是一个返回记录列表的存储过程。

public List<BasicInfo> SelectStudent()
{
    ConnectionString();//Contain Connection string
    List<BasicInfo> entities = new List<BasicInfo>();
    SqlCommand cmd = new SqlCommand("usp_GetAllStudentData", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    conn.Open();
    SqlDataReader rdr = cmd.ExecuteReader();
    while(rdr.Read())
    {
        BasicInfo inf = new BasicInfo();
        inf.FirstName = (string)rdr["FirstName"];
        .....//other required value are assigned to class members.
        //inf.Gender = (Gender)(int)rdr["Gender"];
        inf.Country = (Country)(int)rdr["Country"];  // Getting run time exception here 
        entities.Add(inf);
    }
    return entities;
}

数据在数据库中的存储方式

你们能告诉我转换枚举值的最佳方法是什么吗?

或者让我知道是否有其他方法来解决这个问题。

表设计

InvalidCastException,从ASP中的SqlDataReader获取enum值.净MVC

如果您的数据库字段包含NULL值,那么您的代码的结果是无效强制转换异常

例如

 object x = DbNull.Value;          // A null value on the db is represented by DbNull.Value
 inf.Country = (Country)(int)x;    // Gives the Invalid Cast Exception

如何修复取决于你想对空值做什么。如果你不允许国家为空值,那么你应该修改代码,接受无效输入并阻止这些输入(不要忘记将Country字段设置为不允许数据库表上的null值)

如果您接受空值,那么我建议在您的国家enum中添加另一个条目

public enum Country
{
  Australia = 0,
  Bangladesh,
  England,
  France,
  Usa,
  // <=== new countries should be added here....
  Undefined = 9999
}

并将读取代码更改为

int ordinal = rdr.GetOrdinal("Country");
inf.Country = rdr.IsDBNull(ordinal) ? Country.Undefined
                                    : (Country)(int)rdr["Country"];

从你的评论看来,你已经将枚举的数值存储在一个varchar列中,将你的数字转换为字符串如果要将此字符串转换回适当的enum值,则应该使用enum。TryParse,但是返回的转换并不像看起来那么简单。

如果你还想检查空值,那么:

int ordinal = rdr.GetOrdinal("Country");
// Check for null value....
if(rdr.IsDBNull(ordinal))
    inf.Country = Country.Undefined;
else
{
    // OK, not null, but what if it is "ABC"??
    if(!Enum.TryParse(rdr["Country"].ToString(), out inf.Country))
       inf.Country = Country.Undefined;
    // OK, but what if it is a number not defined in the coutry enum (IE "88")
    if(!Enum.IsDefined(typeof(Country), inf.Country))
       inf.Country = Country.Undefined;
}

如你所见,如果没有特殊的原因,那么我建议将枚举值存储为整数而不是字符串。

try this

 if (rdr["Country"]!=DBNull.Value)
 {
 inf.Country  =(Country)Enum.ToObject(typeof(Country) , rdr["Country"].ToString());
 }