InvalidCastException long to ulong
我有以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static T ExecuteScalar<T>( string query, SqlConnection connection, params SqlParameter[] parameters) where T : new() { // Create SqlCommand SqlCommand command = CreateCommand(query, connection, parameters); // Execute command using ExecuteScalar object result = command.ExecuteScalar(); // Return value as expected type if (result == null || result is DBNull) return default(T); return (T)result; } |
我想让数据库的
方法调用1生成错误:
1 2 3 4 | ulong minActiveRowversion = SqlUtils.ExecuteScalar<ulong>( "SELECT CAST(MIN_ACTIVE_ROWVERSION() AS BIGINT)" , _connectionString); |
错误:
1 |
方法调用2工作正常:
1 2 3 4 | ulong minActiveRowversion = (ulong)SqlUtils.ExecuteScalar<long>( "SELECT CAST(MIN_ACTIVE_ROWVERSION() AS BIGINT)" , _connectionString); |
我不明白这是怎么可能的,因为
1 2 | object result | 1955612 result.GetType() | {Name ="Int64" FullName ="System.Int64"} |
为什么?
只能将值类型取消对其原始类型的绑定。在您的案例中,演员组首先需要从
有关详细信息,请参阅此问题:
为什么我不能把一个整型取为十进制?
它还链接了埃里克·利珀特的一篇博客文章。
怎么
如你所知,一种方法是在铸造到
如注释所述,另一种方法是使用转换例程(
这可能通过使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static T ExecuteScalar<T>( Func<object, T> conversionFunctor, string query, SqlConnection connection, params SqlParameter[] parameters) where T : new() { // Create SqlCommand SqlCommand command = CreateCommand(query, connection, parameters); // Execute command using ExecuteScalar object result = command.ExecuteScalar(); // Return value as expected type if (result == null || result is DBNull) return default(T); return conversionFunctor(result); } |
拨打电话:
1 2 3 4 5 | ulong minActiveRowversion = SqlUtils.ExecuteScalar<ulong>( Convert.ToUInt64, "SELECT CAST(MIN_ACTIVE_ROWVERSION() AS BIGINT)" , _connectionString); |
Adam的答案正确地识别了问题;这里有一个解决方案:您可以使用Linq取消对任何类型的装箱,只要它可以通过内置或自定义转换转换转换转换为
1 2 3 4 5 6 7 8 9 10 |
此方法生成一个LINQ表达式,该表达式首先将对象取消对其实际类型的绑定,然后应用转换。替换方法的最后一行
1 | return (T)result; |
具有
1 | return UnboxUnchecked<T>(result); |
让它发挥作用。
下面是一篇文章的链接,该文章解释了如何通过缓存编译的lambda来提高这种转换的效率。