41

これを行うためのより良い/よりクリーンな方法はありますか?

int stockvalue = 0;
if (!Convert.IsDBNull(reader["StockValue"]))
    stockvalue = (int)reader["StockValue"];
4

13 に答える 13

63

The shortest (IMHO) is:

int stockvalue = (reader["StockValue"] as int?) ?? 0;

Explanation:

  • If reader["StockValue"] is of type int, the value will be returned, and the "??" operator will return the result
  • If reader["StockValue"] is NOT of type int (e.g. DBNull), null will be returned, and the "??" operator will return the value 0 (zero).
于 2010-03-12T14:22:42.223 に答える
31

私がこれを処理する方法は

int? stockvalue = reader["StockValue"] as int?;

とてもシンプルですっきりとした一行。何らかの理由で null 値を絶対に持てない場合 (値に意味があるかどうか、またはプリミティブ型に統一されているかどうかを知りたいため、通常は理由が不十分です)、次のようにします。

int stockvalue = (reader["StockValue"] as int?).GetValueOrDefault(-1);
于 2010-03-12T14:17:57.133 に答える
13

数日前に拡張メソッドを書きました。それを使用することで、次のことができます。

int? stockvalue = reader.GetValue<int?>("StockValue");

拡張方法は次のとおりです (必要に応じて変更してください)。

public static class ReaderHelper
{
    public static bool IsNullableType(Type valueType)
    {
        return (valueType.IsGenericType &&
            valueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
    }

    public static T GetValue<T>(this IDataReader reader, string columnName)
    {
        object value = reader[columnName];
        Type valueType = typeof(T);
        if (value != DBNull.Value)
        {
            if (!IsNullableType(valueType))
            {
                return (T)Convert.ChangeType(value, valueType);
            }
            else
            {
                NullableConverter nc = new NullableConverter(valueType);
                return (T)Convert.ChangeType(value, nc.UnderlyingType);
            }
        }
        return default(T);
    }
}
于 2010-03-12T16:35:29.573 に答える
10
int? stockvalue = (int?)(!Convert.IsDBNull(result) ? result : null);

DBNullがコードに確実に伝わるようにするための1つの可能な解決策。私たちのグループでは、ベスト プラクティスとして、本当に必要な場合を除き、データベースに NULL 列を許可しないようにしています。それを処理するためのコーディングにはより多くのオーバーヘッドがあり、問題を再考するだけで必要なくなる場合があります。

于 2010-03-12T14:05:45.800 に答える
7

を参照すると便利ですがreader["StockValue"]、あまり効率的ではありません。また、 type を返すため、厳密に型指定されていませんobject

代わりに、コード内で次のようにします。

int stockValueOrdinal = reader.GetOrdinal("StockValue");
int? stockValue = reader.IsDbNull(stockValueOrdinal) ?
    null : 
    reader.GetInt32(stockValueOrdinal);

もちろん、すべての序数を一度に取得してから、コード全体で使用することをお勧めします。

于 2010-03-12T14:18:27.237 に答える
7

はい、使用できますint? 。この方法では、デフォルト値を 0 ではなく null にすることができます。stockvalue の結果が 0 になる可能性があるため、データベースが 0 か null かについて混乱することはありません。たとえば、このように (pre nullable)、値が割り当てられていないことを表す -1 のデフォルトの初期化がありました。個人的には、これは少し危険だと思いました。-1 に設定するのを忘れると、追跡が非常に困難なデータ破損の問題が発生する可能性があるからです。

http://msdn.microsoft.com/en-us/library/2cf62fcy(VS.80).aspx

int? stockvalue = null;

if (!Convert.IsDBNull(reader["StockValue"]))
    stockvalue = (int)reader["StockValue"];

//Then you can check 

if(stockValue.HasValue)
{
  // do something here.
}
于 2010-03-12T13:58:10.670 に答える
3
int stockvalue = reader["StockValue"] != DbNull.Value ? Convert.ToInt32(reader["StockValue"]) : 0;
于 2010-05-31T11:34:13.967 に答える
1

これが1つの方法です。

int stockvalue = Convert.IsDbNull(reader["StockValue"]) ? 0 : (int)reader["StockValue"];

TryParse を使用することもできます

int stockvalue = 0
Int32.TryParse(reader["StockValue"].ToString(), out stockvalue);

あなたに合った方法を教えてください

于 2010-03-12T13:58:50.983 に答える
1

この変換を DB クエリで直接行うことができるため、特殊なケースをすべて回避できます。

ただし、DB から NULL の代わりに「0」を返すと情報が失われるため、コードでそのフォームを一貫して使用できない限り、それを「よりクリーン」とは呼びません。

于 2010-03-12T13:59:18.093 に答える
0

あまり。メソッドにカプセル化できます。

public int getDBIntValue(object value, int defaultValue) {
  if (!Convert.IsDBNull(value)) {
    return (int)value;
  }
  else {
    return defaultValue;
  }

そして、次のように呼び出します。

stockVaue = getDBIntVaue(reader["StockValue"], 0);

またはcoalesce、クエリで を使用して、戻り値を強制的に非 null にすることもできます。

編集 - 受け取ったコメントに基づいてダム コード エラーを修正しました。

于 2010-03-12T13:59:46.580 に答える
0
int? stockValue = reader["StockValue"] == null || reader["StockValue"] == DBNull.Value ? null : (int?)reader["StockValue"];
于 2010-03-12T16:42:27.997 に答える
0

タイプを使用してNullable<int>ください...int?略して

于 2010-03-12T13:58:21.540 に答える
0

私のプロジェクトには、次の 2 つの拡張メソッドがあります。

    public static T GetValueSafe<T>(this IDataReader dataReader, string columnName, Func<IDataReader, int, T> valueExtractor)
        where T : class 
    {
        T value;
        if (dataReader.TryGetValueSafe(columnName, valueExtractor, out value))
        {
            return value;
        }

        return null;
    }

    public static bool TryGetValueSafe<T>(this IDataReader dataReader, string columnName, Func<IDataReader, int, T> valueExtractor, out T value)
    {
        int ordinal = dataReader.GetOrdinal(columnName);

        if (!dataReader.IsDBNull(ordinal))
        {
            // Get value.
            value = valueExtractor.Invoke(dataReader, ordinal);

            return true;
        }

        value = default(T);
        return false;
    }

使用法は次のようになります。

string companyName = dataReader.GetValueSafe("CompanyName", (reader, ordinal) => reader.GetString(ordinal));
于 2010-03-12T14:39:44.783 に答える