如何使用SqlDataRecord处理Nullable类型

我正在解析XML(LINQ to XML),并且我在元素/属性为空的情况下使用可空类型( int?decimal? )。 但是,在构建我的集合以传递给DB(使用TVP)时,我不知道如何处理值实际为null的情况。 我无法将null传递给SqlDataRecord SetInt32或SetDecimal,我不想设置为零….我实际上希望它为null。

告诉我int没有超载?

下面的计数是可以为空的类型( int? Count)

 SqlDataRecord rec = new SqlDataRecord( new SqlMetaData("Name", SqlDbType.VarChar, 50), new SqlMetaData("Type", SqlDbType.VarChar, 50), new SqlMetaData("Count", SqlDbType.Int)); rec.SetString(0, dm.Name); rec.SetString(1, dm.Type); rec.SetString(2, dm.Count); 

任何想法如何处理这个而不传递零(保持null)?

扩展方法:

 static class SqlDataRecordExtensions { static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) { if (value.HasValue) rec.SetInt32(index, value.GetValueOrDefault()); else rec.SetDBNull(index); } } 

或者,按照D Stanley的建议使用SetSqlInt32

 static class SqlDataRecordExtensions { static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) { rec.SetSqlInt32(index, value.HasValue ? value.GetValueOrDefault() : SqlInt32.Null); // ^^^^^^^^^^^^^^^^^^^^^^^^^ // You can leave out the cast to (SqlInt32), // because the conversion is implicit } } 

请注意,2013年12月9日:由于评论而回到这个答案,我注意到一个很小的改进机会,基于Eric Lippert关于可以为空的微优化的系列,可以在http://ericlippert.com/2012/12找到/ 20 / nullable-micro-optimizations-part-one / 。

简而言之,虽然Value属性需要较少的输入,因此对程序员而言可能更为理想,但如果HasValue为false,则必须抛出exception。 另一方面, GetValueOrDefault()方法是一个简单的字段访问。 因此, GetValueOrDefault()需要更少的指令并且更有可能被内联,因此对于编译器和处理器来说它更为理想。

我从未使用过SqlDataRecord ,但是在使用DataTableDataRow ,或者在使用参数化查询时,我使用DBNull.Value指定null

使用SqlDataRecord ,看起来您可以使用SetDBNull方法。

应该使用SetSqlInt32而不是SetString 。 尝试

 rec.SetSqlInt32(2, (dm.Count.HasValue ? new SqlInt32(dm.Count) : SqlInt32.Null) ); 

//我在检查或处理可空类型时发现这对我来说是最好的//在我的例子中我检查存储在String []数组中的值

 sqlcmdUpdateRecord.Parameters.AddWithValue("@strSomeValue", (strRecord[(int) DataFields.SomeDataField] as object) ?? DBNull.Value);