C# 取消绑定DataRow中的非类型化字段而不发生强制转换错误

C# 取消绑定DataRow中的非类型化字段而不发生强制转换错误,c#,sql-server,unboxing,C#,Sql Server,Unboxing,我的ASP.Net应用程序的数据层调用一个存储过程,以便在登录时获取关于访问者的少量(一条记录)信息。我输入他们的电话号码,存储过程使用一个简单的SELECT返回5个字段,第一个字段是主键BIGINT。我的数据层获取数据行并尝试使用它创建数据对象。在数据对象中,表示主键的属性是Int64。看起来是这样的: sub = new PersistentSubscriber((String) dr["UserFirstName"], (String) dr["UserLastName"

我的ASP.Net应用程序的数据层调用一个存储过程,以便在登录时获取关于访问者的少量(一条记录)信息。我输入他们的电话号码,存储过程使用一个简单的SELECT返回5个字段,第一个字段是主键BIGINT。我的数据层获取数据行并尝试使用它创建数据对象。在数据对象中,表示主键的属性是Int64。看起来是这样的:

 sub = new PersistentSubscriber((String) dr["UserFirstName"],
        (String) dr["UserLastName"],
        phoneNumber, (Int64) dr["UserId"], (Byte) dr["SubscriberStatus"]);
我发现当我有一个大的主键值时,一切都很好,比如88698。然而,当我得到一个小的,如999,我得到一个“指定的强制转换是无效的”错误时,试图设置该主键属性。当我尝试在即时窗口中使用它时,我得到以下结果:

?(Int64)dr["UserId"]
Cannot unbox 'dr["UserId"]' as a 'long'
?(int)dr["UserId"]
999
?(Int32)dr["UserId"]
999

在不使用类型化数据集的情况下,我做错了什么呢?

试着给
Int64.TryParse
一个镜头

long userId;
if(Int64.TryParse(dr["UserId"], out userId))
{
    // successful conversion
}

当然,我在挖掘一个老问题,但它在靠近顶部的谷歌搜索中出现了,所以为什么不

你听说过吗?它们允许您以强类型方式访问数据行中的字段。这在linq查询中非常有用,根据我的经验,它比调用DataTable.Select()要快得多

只需在项目中添加对
System.Data.DataSetExtensions
的引用,就可以使用它们了

例如:

Int64 value = dr.Field<Int64>("UserId");

dr.SetField("UserId", value);
Int64 value=dr.Field(“UserId”);
dr.SetField(“UserId”,值);

对于像Convert和TryParse这样的转换调用,我想这是可行的,但我更关心的是“为什么”我需要这样做?999是有效的Int32,就像它是有效的Int64一样。我为什么要做任何转换呢?如果我知道它永远不会超过这个型号,我应该很乐意去。