1

C# のレコードセットから変換する作業コードがありますが、他のアプローチにも出くわし、その使用法を調査しています。テストコードは次のとおりです。

`using (DataTableReader reader = new DataTableReader(ds2.Tables[0]))
 {
    while (reader.Read())
    {       

    //sample of working code. The values are on the far right.
    string val1 = reader[0] is DBNull ? default(string) : reader[0].ToString(); //value = "test"
    int val2 = reader[2] is DBNull ? default(int) : Convert.ToInt32(reader[2].ToString());  //value = 23
    bool val3 = reader[26] is DBNull ? default(bool) : reader[26].ToString() == "1" ? true : false;     //value = true
    DateTime val4 = reader[16] is DBNull ? default(DateTime) : Convert.ToDateTime(reader[16].ToString());  //value=  10/6/2013 6:31:33 AM

    //the first approach
    string val5 = reader[0] as string;
    int? val6 = reader[2] as int? ?? default(int);
    bool? val7 = reader[26] as bool? ?? default(bool);
    DateTime? val8 = reader[16] as DateTime? ?? default(DateTime);

    //the second approach
    string val9 = reader[0] is DBNull ? default(string) : reader.GetString(0);
    int val10 = reader[2] is DBNull ? default(int) : reader.GetInt32(2); ;
    bool val11 = reader[26] is DBNull ? default(bool) : reader.GetBoolean(26);
    DateTime val12 = reader[16] is DBNull ? default(DateTime) : reader.GetDateTime(16);

    //the third approach
    var val13 = reader[0] is DBNull ? default(string) : (string)reader[0];
    int val14 = reader[2] is DBNull ? default(int) : (int)reader[2]; ;
    bool val15 = reader[26] is DBNull ? default(bool) : (bool)reader[26];
    DateTime val16 = reader[16] is DBNull ? default(DateTime) : (DateTime)reader[16];

    //the 4th approach                
    int val17 = reader[2] is DBNull ? default(int) : (int) Int32.Parse(reader[2].ToString());
    bool val18 = reader[26] is DBNull ? default(bool) : (bool) Boolean.Parse( reader[26].ToString()=="1"? "true" : "false");
    DateTime val19 = reader[16] is DBNull ? default(DateTime) : (DateTime) DateTime.Parse(reader[16].ToString());

    }
}`

この SO Q&Aは、1 番目と 2 番目のアプローチのサンプルを示しています。3 番目のアプローチは、この SO Q&Aから採用しました。四つ目のアプローチはここからだ。

最初のアプローチでは、as 演算子が ?? と組み合わされます。as 演算子がキャストを処理し、DBNull をチェックする限り、デフォルト値の演算子。このコードを使用すると、文字列の null 値と残りのデフォルト値を取得しています。これは、「as」演算子が失敗していることを示しています。

2 番目の方法では、リーダーの Getxxxx() メソッドを使用します。ただし、これにより、 「型 'System.Data.SqlTypes.SqlString' のオブジェクトを型 'System.String' にキャストできません」という例外がスローされます。文字列と「指定されたキャストは無効です。」他の人のために。3 番目のアプローチはキャストを使用し、2 番目のアプローチと同じ種類の例外を生成します。

4 番目のアプローチが機能し、最初にデータを文字列に変換し、文字列を解析して、最後に目的の型にキャストします。TryParse()Convert.ChangeType( )を使用してさらにいくつか出くわしましたが、それらはより冗長です。

私の質問は、これらの他のアプローチは他の人にも有効であるように見えます (それらは回答であり、支持されています) が、私がそれらを使用するときはなぜですか? ここで何が間違っていますか?機能させることができる場合、これらのうちどれが最も効率的なアプローチですか?

編集: @usr で提案されているように、いくつかのヘルパー メソッドを使用する必要があります。作業コードに使用するヘルパー メソッドと、使用例を次に示します。

    public static T GetColumnValue<T>(this DataTableReader reader, string columnName)
    {
        T result = default(T);
        int index = reader.GetOrdinal(columnName);

        if (!reader.IsDBNull(index))
        {                                
            result = (T)Convert.ChangeType(reader[index].ToString(), typeof(T));                                
        }

        return result;         
    }

    //used as 
    string val1 = reader.GetColumnValue<string>("Column1"); 
    int val2 = reader.GetColumnValue<int>("Column2"); 
    bool val3 = reader.GetColumnValue<bool>("Column3"); 
    DateTime val4 = reader.GetColumnValue<DateTime>("Column4"); 

もちろん、これは他のアプローチでは機能しません。なぜ他のアプローチが機能しないのか、私はまだ興味があります。ありがとう。

4

0 に答える 0