我从SQL数据读取器(MS SQL作为数据存储区)中获取异常,并且我想知道哪个列名会导致抛出此异常。但我无法在InnerException中找到它..无处。
((System.InvalidOperationException)ex.InnerException).StackTrace:
System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i)
...
请将它隐藏在哪里?
答案 0 :(得分:2)
你做不到。数据读取器不会在其堆栈跟踪中进行通信。你可以做的是将数据阅读器的使用包装在另一个类中。在我正在研究的项目中,我们使用了扩展方法。该课程如下:
public static class DataRecordExtensions
{
public static byte GetByte(this IDataRecord record, string name)
{
return Get<byte>(record, name);
}
public static short GetInt16(this IDataRecord record, string name)
{
return Get<short>(record, name);
}
public static int GetInt32(this IDataRecord record, string name)
{
return Get<int>(record, name);
}
private static T Get<T>(IDataRecord record, string name)
{
// When the column was not found, an IndexOutOfRangeException will be
// thrown. The message will contain the name argument.
object value = record[name];
try
{
return (T)value;
}
catch (InvalidCastException ex)
{
throw BuildMoreExpressiveException<T>(record, name, value, ex);
}
}
private static InvalidCastException BuildMoreExpressiveException<T>(
IDataRecord record, string name,
object value, InvalidCastException ex)
{
string exceptionMessage = string.Format(CultureInfo.InvariantCulture,
"Could not cast from {0} to {1}. Column name '{2}' of {3} " +
"could not be cast. {4}",
value == null ? "<null>" : value.GetType().Name,
typeof(T).Name, name, record.GetType().FullName, ex.Message);
return new InvalidCastException(exceptionMessage, ex);
}
}
您可以按如下方式使用它:
using (var reader = SqlHelper.ExecuteReader(...))
{
while (reader.Read())
{
yield return new Order()
{
OrderId = reader.GetInt32("orderId"),
ItemId = reader.GetInt32("itemId")
};
}
}
顺便说一句。这样的课程还允许您返回Nullable<T>
个对象并摆脱您需要执行的那些手动DbNull
转换。