2017-08-28 14 views
0

なぜ私はこのエラーが発生するのか分かりません。 整数の文字列ステータスと整数valortotalを持つデータテーブルがあります。キャストが有効でない

選択クエリを使用してデータを自分のPedido変数にインポートしようとすると、キャストエラーが発生します。 これは

public class Pedido 
{ 
    public int numeromesa { get; set; } 
    public int valorpedido { get; set; } 
    public string status { get; set; } 

} 

は今、これは私が選択クエリ

public List<Pedido> listaPedido() 
    { 
     vsql = "SELECT * FROM pedidos"; 
     List<Pedido> bancoPedidos = new List<Pedido>(); 
     NpgsqlCommand objcmd = null; 
     objcmd = new NpgsqlCommand(vsql, con); 
       NpgsqlDataAdapter adp = new NpgsqlDataAdapter(objcmd); 
       DataTable dt = new DataTable(); 
       adp.Fill(dt); 
       foreach (DataRow row in dt.Rows) 
       { 
       //This is line 185 
        Pedido p = new Pedido 
        { 
         numeromesa = (int)row[1], 
         status = (string)row[2], 
         valorpedido = (int)row[3]        
        }; 
        bancoPedidos.Add(p); 

        return bancoPedidos; 
     } 
を使用し作られた方法がある

問題は私が取る場合valorpedido変数であると思われるテーブルからデータを受信するクラスです。それは、コードが正常に動作します

************例外テキスト************* System.InvalidCastException:指定されたキャストはありません有効です。 PostgreSQL.cs:ライン185

+0

インデックスはゼロベースなので、結果セットに4つのカラムがない場合は、ロー[0]、ロー[1]、ロー[2]でなければなりません。列名で索引付けする方がよい。序数ベースの索引付けに関連して「select * from ...」は非常に脆弱なアプローチです。 – dlatikay

+0

1ではなく0からインデックスを作成すべきではないですか? – juharr

+0

valortotalはNULL可能ですか?あなたは、他の答えのコメントの1つに「dbnullにキャストできません」と言いました。 – cost

答えて

0

エラーが上であるので:それはデータベースから来るとき

valorpedido = (int)row[3] 

問題は、その行である[3]は整数型ではありません。

データ列とのインデックスが0であるため、おそらく1つの列が外れている可能性があります。

2

元のコードは、インデックスで列をアドレス指定します。インデックスはゼロから始まり、スキーマの変更に合わせて位置がずれる傾向があります。
代わりに、列にアクセスするために名前を使用します。

var p = new Pedido 
{ 
    numeromesa = (int)row["numeromesa"], 
    status = row["status"].ToString(), 
    valorpedido = (int)row["valortotal"] 
}; 

このコードはstatusvalortotalどちらがNULL可能であることを前提としています。彼らは、あなたがそれを考慮する必要がありました場合は、例:

public class Pedido 
{ 
    public int numeromesa { get; set; } 
    public int? valorpedido { get; set; } 
    public string status { get; set; } 
} 

var p = new Pedido 
{ 
    numeromesa = (int)row["numeromesa"], 
    status = row["status"].ToString() 
}; 

if(row["valortotal"].Equals(DBNull.Value)) 
{ 
    p.valorpedido = null; 
} 
else 
{ 
    p.valorpedido = Convert.ToInt32(row["valortotal"]); 
} 

代わりに序の名前で値を調べるのパフォーマンスの低下は、私たちが「時を除いて(この文脈では無視できます何千ものレコードについて話しています)、重要な利点が1つあります。pedidosテーブルまたはビュースキーマの変更によって列の順序が変わった場合、コードは引き続き機能します。もともと書かれているように、それは壊れるでしょう。

+0

インデックスは問題ではありません。テーブルの[0]インデックスは自動インクリメントIDで、[3]インデックスは正しいです。名前に変更しようとすると、同じエラーが表示されます。 –

+0

私はvalortotal/valorpedidoでこれを表示するための答えを更新しました。このパターンが複数回ある場合は、クラッタを減らすためのユーティリティ関数を記述します。 – dlatikay

+0

Dbnull.Valueは存在せず、dbnullだけを試して、nullでも同じエラーが発生する "dbnullから他の型にオブジェクトをキャストすることはできない –

関連する問題