2016-10-16 10 views
1

私はこのコードを実行時にSystem.InvalidCastExceptionを取得しています:InvalidCastExceptionが、ASP.NETでSqlDataReaderのからフェッチする列挙値MVC

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

Modelクラス:

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; 
} 

How the data is stored in the database

君たちは私が列挙値をキャストするための最良の方法は何か知っていることはできますか?

この問題を解決する別の方法がある場合はお知らせください。

Table Design

答えて

1

データベースのフィールドは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 

のためにあなたがしたいかに依存しますどのように修正しますnull値で行う国のNULL値を許可しない場合は、無効な入力を受け入れ、これらの入力をブロックするコードを修正する必要があります(データベースフィールドにNULL値を許可しないように国フィールドを設定することを忘れないでください)。

私はあなたが列挙型の数値を格納しているようだあなたの国の列挙型

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"]; 

にあなたの読書のコードを変更することをお勧めその後、NULL値を受け入れますvarchar列変換であなたの数字を文字列に入れよう この文字列を適切な列挙型の値に変換したい場合は、Enum.TryParseを使用するべきですが、変換後の文字列はそれほど単純ではありません。だから、

あなたはまだそれからNULL値を確認したい場合:特別な理由がない場合、私は整数として列挙値を格納することをお勧めしていないとして、

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; 
} 

をあなたが見ることができるように文字列。これにより、コードの柔軟性と将来のこの変数の変更が可能になります。

+0

を試してみてください。 – Beginners

+0

データベーステーブルの「国」列はどのように定義されていますか?私はそのデータ型がIntであると仮定します。 – Steve

+0

いいえ、そのvarchar型です。 – Beginners

0

は私が受け入れて、null値の概念が、そのInvalidCast私に与えられた例外を使用していたこの

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

"渡される値は列挙型の列挙型または基底型でなければなりません"( 'System.ArgumentException')例外 – Beginners

+0

渡される値は列挙型でなければなりません列挙型の基本型またはInt32などの列挙型の基本型です。 – Beginners

関連する問題