如果我这样做:
DataSet ds = GetMyDataset();
try
{
string somevalue = ds.Tables[0].Rows[0]["col1"];
}
catch
{
//maybe something was null
}
有没有一种不使用try / catch检查空值的好方法?只是我不关心“col1”中的值是否为空,或者如果“col1”不存在,或者如果没有返回行,或者如果表不存在,则不在乎!
也许我应该关心? :) 也许try / catch是接近这个的最佳方式,但我只是想知道是否还有其他方法可以做到这一点?
谢谢!
答案 0 :(得分:7)
不关心桌子或柱子有点奇怪。
例如,期待table[0].Rows.Count == 0
是一种更为常见的做法。
检查NULL值的最佳方法是使用if(...) ... else ...
最糟糕的方式是等待例外(以任何方式)。
答案 1 :(得分:4)
if (ds == null
|| ds.Tables == null
|| ds.Tables.Count == 0
|| ds.Tables[0].Rows == null
|| ds.Tables[0].Rows.Count == 0
|| ds.Tables[0].Rows[0].IsNull("col1")
)
//there is no data...
...
答案 2 :(得分:3)
如果您想确保您的代码不会失败,您实际上必须检查层次结构中的所有元素,例如:
string someValue = "";
if (ds != null &&
ds.Tables != null &&
ds.Tables.Any() &&
ds.Tables[0].Rows != null &&
ds.Tables[0].Rows.Any() &&
ds.Tables[0].Rows[0]["col1"] != DBNull.Value)
{
someValue = ds.Tables[0].Rows[0]["col1"];
}
答案 3 :(得分:2)
DataSet ds = GetMyDataset();
string somevalue = ds != null ? ds.Tables[0].Rows[0]["col1"].ToString() : null;
答案 4 :(得分:1)
你或许可以使用可空的三元组'??',但我认为返回的null是'DBNull'而不是'null'。
例子是......
string somevalue = ds.Tables[0].Rows[0]["col1"] ?? "";
答案 5 :(得分:1)
做一些检查:
string somevalue = String.Empty;
if (ds.Tables.Count > 0)
{
System.Data.DataTable dt = ds.Tables[0];
if (dt.Rows.Count > 0)
{
System.Data.DataRow dr = dt.Rows[0];
if (dt.Columns.Count>0 && dt.Columns.Contains("col1"))
{
somevalue = dr["col1"].ToString();
}
}
}
答案 6 :(得分:0)
你必须从顶部开始(这是DataSet)逐个检查所有null(或其他null类型)
if(ds!= null) if(table!= null) ...
你可以不用,但你的代码更容易出错。
答案 7 :(得分:0)
从维护的角度来看,你正在做的事情是非常可取的。
否则,您必须:检查DS是否为null,检查DataSet中是否有任何表,检查表中是否有任何行,检查列是否存在,检查以查看如果列中有任何数据。
它肯定会消除很多繁琐的代码。
答案 8 :(得分:0)
我过去使用的是Null测试的一个小包装器,它返回一个默认值。例如:
/// <summary>
/// Test DBValue for DBNull and return NullReplaceValue if DBValue is DBNull
/// </summary>
/// <returns>Returns NullReplaceValue if DBValue is DBNull</returns>
public static string NullStr(object DBValue, string NullReplaceValue)
{
if (object.ReferenceEquals(DBValue, DBNull.Value)) {
return NullReplaceValue;
} else {
return Convert.ToString(DBValue);
}
}
使用中:
string somevalue = MyNullTests.NullStr(ds.Tables[0].Rows[0]["col1"], "Value was null");
答案 9 :(得分:0)
我认为你应该明确表示你并不关心所有这些事情,这意味着你应该明确地处理每一个案例:
if (ds.Tables.Count == 0)
return null;
var table = ds.Tables[0];
if (table.Rows.Count == 0)
return null;
if (!table.Columns.Contains("col1"))
return null;
var row = ds.Rows[0];
if (row.IsNull("col1"))
return null;
return row["col1"]
这是更多的代码,但对我而言,它更清楚地传达了意图。
答案 10 :(得分:0)
我认为May be Monad对于这种情况是最好的(Sample来自源代码):
public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator) where TResult : class where TInput : class { if (o == null) return null; return evaluator(o); } string postCode = this.With(x => person) .With(x => x.Address) .With(x => x.PostCode)
对于您的情况类似于:
ds.With(x=>Tables[0]).With(x=>x.Rows).With(x=>x[0])...
您将创建一个扩展类并使用它而不必担心空引用,另外Return
方法对于您看到链接很有用。
答案 11 :(得分:0)
如果你真的要发送随机的,未经验证的数据集,索引和名称,你可以像这样做一个辅助方法:
public static Object GetDataSetValue(DataSet dataSet, int tableIndex, int rowIndex, string columnName)
{
Object value = null;
if (dataSet != null
&& tableIndex >= 0
&& tableIndex < dataSet.Tables.Count
&& rowIndex >= 0
&& rowIndex < dataSet.Tables[tableIndex].Rows.Count
&& dataSet.Tables[tableIndex].Columns.Contains(columnName))
{
value = dataSet.Tables[tableIndex].Rows[rowIndex][columnName];
}
return value;
}
然后使用类似GetDataSetValue(ds, 0, 0, "col1")
的内容。
答案 12 :(得分:0)
我讨厌不得不处理不能保证标准结果集的数据访问层:任何给定的SQL查询或存储过程应该始终返回相同的结果集模式。处理空集(又名DataTables)很容易。处理任意缺失的对象引用......不是那么多。
正确的答案是修复您的数据访问代码,使其返回一致的架构。
如果不这样做,如果我必须处理像我这样做的代码:
DataSet ds = ExecuteStoredProcedure();
DataTable dt = ( ds != null && ds.Tables != null ? ds.Tables[0] : null ) ;
DataRow dr = ( dt != null && dt.Rows != null ? dt.Rows[0] : null ) ;
object o = ( dr != null ? dr["someColumn"]) : null ) ;
string someColumn = (string) colName ;
在调试器中或通过日志记录调试很容易。给出5个值的集合,您可以很容易地看到存在的内容和缺失的内容。它可以很容易地看出违反了什么假设(约束?)。
答案 13 :(得分:-1)
检查DBNull.Value,例如
if (ds.Tables[0].Rows[0]["col1"] != DBNull.Value)