IDataReader を使うときそのままだとこんな感じだと思うんですが、
int intValue = (int) reader["int_field"]; string strValue = (string) reader["str_field"];
NULL のときとかちょっと面倒です。(なんで IDataReader.IsDBnull には IsDBNull(string name) みたいなオーバーロードがないんだろう
Nullable<int> nullableValue = null; if (!reader.IsDBNull(reader.GetOrdinal("nullable_field"))) { nullableValue = (int) reader["nullable_field"]; }
なのでこんな風にできるようにしたい。
int intValue = reader.Field<int>("int_field"); string strValue = reader.Field<string>("str_field"); Nullable<int> nullableValue = reader.Field<Nullable<int>>("nullable_field"); int ifNullValue = reader.Field<int>("if_null_field", ifNull:-1);
3.5以上なら拡張メソッド作ればいいんですが... 残念ながら 2.0 な環境だったのでこんなヘルパクラスを作って実装しました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DataReaderHelper : IDataReader | |
{ | |
public DataReaderHelper(IDataReader reader) | |
{ | |
if (reader == null) throw new ArgumentNullException("reader"); | |
_reader = reader; | |
} | |
private readonly IDataReader _reader; | |
public T Field<T>(string fieldName) | |
{ | |
return Field<T>(_reader, fieldName, default(T), false); | |
} | |
public T Field<T>(string fieldName, T ifNull) | |
{ | |
return Field<T>(_reader, fieldName, ifNull, true); | |
} | |
public bool IsDBNull(string fieldName) | |
{ | |
return _reader.IsDBNull(_reader.GetOrdinal(fieldName)); | |
} | |
private static T Field<T>(IDataReader reader, string fieldName, T ifNull, bool useIfNull) | |
{ | |
Type type = typeof (T); | |
Type valueType = Nullable.GetUnderlyingType(type); | |
bool typeIsNullable = (valueType != null); | |
if (!typeIsNullable) | |
valueType = type; | |
if (Convert.IsDBNull(reader[fieldName])) | |
{ | |
if (typeIsNullable || !valueType.IsValueType || useIfNull) | |
return ifNull; | |
throw new InvalidCastException(); | |
} | |
return (T)reader[fieldName]; | |
} | |
public void Close() | |
{ | |
_reader.Close(); | |
} | |
public int Depth | |
{ | |
get { return _reader.Depth; } | |
} | |
public DataTable GetSchemaTable() | |
{ | |
return _reader.GetSchemaTable(); | |
} | |
public bool IsClosed | |
{ | |
get { return _reader.IsClosed; } | |
} | |
public bool NextResult() | |
{ | |
return _reader.NextResult(); | |
} | |
public bool Read() | |
{ | |
return _reader.Read(); | |
} | |
public int RecordsAffected | |
{ | |
get { return _reader.RecordsAffected; } | |
} | |
public void Dispose() | |
{ | |
_reader.Dispose(); | |
} | |
public int FieldCount | |
{ | |
get { return _reader.FieldCount; } | |
} | |
public bool GetBoolean(int i) | |
{ | |
return _reader.GetBoolean(i); | |
} | |
public byte GetByte(int i) | |
{ | |
return _reader.GetByte(i); | |
} | |
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) | |
{ | |
return _reader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); | |
} | |
public char GetChar(int i) | |
{ | |
return _reader.GetChar(i); | |
} | |
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) | |
{ | |
return _reader.GetChars(i, fieldoffset, buffer, bufferoffset, length); | |
} | |
public IDataReader GetData(int i) | |
{ | |
return _reader.GetData(i); | |
} | |
public string GetDataTypeName(int i) | |
{ | |
return _reader.GetDataTypeName(i); | |
} | |
public DateTime GetDateTime(int i) | |
{ | |
return _reader.GetDateTime(i); | |
} | |
public decimal GetDecimal(int i) | |
{ | |
return _reader.GetDecimal(i); | |
} | |
public double GetDouble(int i) | |
{ | |
return _reader.GetDouble(i); | |
} | |
public Type GetFieldType(int i) | |
{ | |
return _reader.GetFieldType(i); | |
} | |
public float GetFloat(int i) | |
{ | |
return _reader.GetFloat(i); | |
} | |
public Guid GetGuid(int i) | |
{ | |
return _reader.GetGuid(i); | |
} | |
public short GetInt16(int i) | |
{ | |
return _reader.GetInt16(i); | |
} | |
public int GetInt32(int i) | |
{ | |
return _reader.GetInt32(i); | |
} | |
public long GetInt64(int i) | |
{ | |
return _reader.GetInt64(i); | |
} | |
public string GetName(int i) | |
{ | |
return _reader.GetName(i); | |
} | |
public int GetOrdinal(string name) | |
{ | |
return _reader.GetOrdinal(name); | |
} | |
public string GetString(int i) | |
{ | |
return _reader.GetString(i); | |
} | |
public object GetValue(int i) | |
{ | |
return _reader.GetValue(i); | |
} | |
public int GetValues(object[] values) | |
{ | |
return _reader.GetValues(values); | |
} | |
public bool IsDBNull(int i) | |
{ | |
return _reader.IsDBNull(i); | |
} | |
public object this[string name] | |
{ | |
get { return _reader[name]; } | |
} | |
public object this[int i] | |
{ | |
get { return _reader[i]; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DataReaderHelper reader = new DataReaderHelper(command.ExecuteReader()); | |
while (reader.Read()) | |
{ | |
int intValue = reader.Field<int>("int_field"); | |
string strValue = reader.Field<string>("str_field"); | |
Nullable<int> nullableValue = reader.Field<Nullable<int>>("nullable_field"); | |
int ifNullValue = reader.Field<int>("if_null_field", ifNull:-1); | |
} |
まあ実際は VB.NET なんですが... これで IDataReader が少し使いやすくなりました。
0 件のコメント:
コメントを投稿