为什么 dataTable.Rows[0]["columnName"] == null。不工作?
why dataTable.Rows[0]["columnName"] == null. not working?
我有如下代码
txtbox1.Text = dtDetails.Rows[0]["columnName"] == null ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
上面的行总是 not null
即使 dtDetails.Rows[0]["columnName"] is null
而
txtbox1.Text = dtDetails.Rows[0]["columnName"] == DBNull.Value ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
完美运行。这是为什么? null
与 DBNull.Value
有何不同
ADO.NET(DataSet
、DataTable
和 DataRow
)表示 SQL NULL
值 DBNull.Value
- 这是为了区分运行时 (C#/.NET) null
和 SQL NULL
.
我强烈建议阅读此 QA:What is the point of DBNull?
您可以简化您的代码,顺便说一句,使用 DataRowExtensions
-(添加对 System.Data.DataSetExtensions.dll
的引用)
txtbox1.Text = dtDetails.Rows[0]["columnName"] == DBNull.Value ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
可改为:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName")?.Trim() ?? "--";
DataRowExtensions.Field<T>( this DataRow row, String name )
扩展方法检查 DBNull.Value
和 returns null
- 否则它 returns 所需的字段没有查找的开销DataRow
值是您的代码当前值的两倍。
2010 年 Visual Studio 的更新
OP 说他们正在使用 Visual Studio 2010(2019 年?!),所以有几个选项:
- Upgrade to Visual Studio 2019。不像从VS2008跳到VS2010,没有
重要的功能已从 VS2010 中删除,而这些功能在 VS2019 中仍然不可用 - 例如,您仍然可以在 VS2019 中以 .NET Framework 2.0 和 Windows XP 为目标。
- 免费的(as in beer) Visual Studio 2019 Community is as-featured as VS2010 and is now free. You can also use the free and open-source Visual Studio Code 也可用于 Visual C# 项目。
- (VS2010 从 VS2008 中删除了有用的东西,比如文档资源管理器、对 .NET Compact Framework 的支持、对象测试台功能,运行 速度变慢,并永久改变了编辑器缩进的工作方式(更糟的是, 我))
如果您必须使用 VS2010(但为什么呢?)您可以修改 MSBuild 项目文件以使用更现代的 C# 编译器 - 但这是一个复杂的过程 - 并且没有 IDE 编辑器支持(因此即使项目构建良好,你也会到处看到红色波浪线)。
- Visual Studio 2012 及更高版本在使用 Visual Studio 2010 SP1 或更高版本文件时不再需要单向项目和解决方案文件升级 - 因此您可以在没有任何人的情况下将 VS2019 与 VS2010 文件一起使用使用 VS2010 抱怨。
您可以更改表达式以执行 Trim()
after ?? "--"
子句:
txtbox1.Text = ( dtDetails.Rows[0].Field<String>("columnName") ?? "--" ).Trim();
您可以使用扩展方法作为 lambda 中的 hacked-on 条件运算符:
static class Extensions
{
public static TOut N<TIn,TOut>( this TIn value, Func<TIn,TOut> whenNotNull )
where TIn : class
where TOut : class
{
if( value == null ) return null;
return whenNotNull( value );
}
}
这样使用:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName").N( v => v.Trim() ) ?? "--";
或进一步扩展:
static class Extensions
{
public static TOut N<TIn,TOut>( this TIn value, Func<TOut> whenNull, Func<TIn,TOut> whenNotNull )
where TIn : class
where TOut : class
{
if( value == null ) return whenNull();
return whenNotNull( value );
}
}
这样使用:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName").N( () => "--", v => v.Trim() );
您必须检查 SQL NULL
而不是 Net Framework null
。它们是两个不同的东西
我有如下代码
txtbox1.Text = dtDetails.Rows[0]["columnName"] == null ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
上面的行总是 not null
即使 dtDetails.Rows[0]["columnName"] is null
而
txtbox1.Text = dtDetails.Rows[0]["columnName"] == DBNull.Value ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
完美运行。这是为什么? null
与 DBNull.Value
ADO.NET(DataSet
、DataTable
和 DataRow
)表示 SQL NULL
值 DBNull.Value
- 这是为了区分运行时 (C#/.NET) null
和 SQL NULL
.
我强烈建议阅读此 QA:What is the point of DBNull?
您可以简化您的代码,顺便说一句,使用 DataRowExtensions
-(添加对 System.Data.DataSetExtensions.dll
的引用)
txtbox1.Text = dtDetails.Rows[0]["columnName"] == DBNull.Value ? "--": dtDetails.Rows[0]["columnName"].ToString().Trim();
可改为:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName")?.Trim() ?? "--";
DataRowExtensions.Field<T>( this DataRow row, String name )
扩展方法检查 DBNull.Value
和 returns null
- 否则它 returns 所需的字段没有查找的开销DataRow
值是您的代码当前值的两倍。
2010 年 Visual Studio 的更新
OP 说他们正在使用 Visual Studio 2010(2019 年?!),所以有几个选项:
- Upgrade to Visual Studio 2019。不像从VS2008跳到VS2010,没有
重要的功能已从 VS2010 中删除,而这些功能在 VS2019 中仍然不可用 - 例如,您仍然可以在 VS2019 中以 .NET Framework 2.0 和 Windows XP 为目标。
- 免费的(as in beer) Visual Studio 2019 Community is as-featured as VS2010 and is now free. You can also use the free and open-source Visual Studio Code 也可用于 Visual C# 项目。
- (VS2010 从 VS2008 中删除了有用的东西,比如文档资源管理器、对 .NET Compact Framework 的支持、对象测试台功能,运行 速度变慢,并永久改变了编辑器缩进的工作方式(更糟的是, 我))
如果您必须使用 VS2010(但为什么呢?)您可以修改 MSBuild 项目文件以使用更现代的 C# 编译器 - 但这是一个复杂的过程 - 并且没有 IDE 编辑器支持(因此即使项目构建良好,你也会到处看到红色波浪线)。
- Visual Studio 2012 及更高版本在使用 Visual Studio 2010 SP1 或更高版本文件时不再需要单向项目和解决方案文件升级 - 因此您可以在没有任何人的情况下将 VS2019 与 VS2010 文件一起使用使用 VS2010 抱怨。
您可以更改表达式以执行
Trim()
after?? "--"
子句:txtbox1.Text = ( dtDetails.Rows[0].Field<String>("columnName") ?? "--" ).Trim();
您可以使用扩展方法作为 lambda 中的 hacked-on 条件运算符:
static class Extensions { public static TOut N<TIn,TOut>( this TIn value, Func<TIn,TOut> whenNotNull ) where TIn : class where TOut : class { if( value == null ) return null; return whenNotNull( value ); } }
这样使用:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName").N( v => v.Trim() ) ?? "--";
或进一步扩展:
static class Extensions { public static TOut N<TIn,TOut>( this TIn value, Func<TOut> whenNull, Func<TIn,TOut> whenNotNull ) where TIn : class where TOut : class { if( value == null ) return whenNull(); return whenNotNull( value ); } }
这样使用:
txtbox1.Text = dtDetails.Rows[0].Field<String>("columnName").N( () => "--", v => v.Trim() );
您必须检查 SQL NULL
而不是 Net Framework null
。它们是两个不同的东西