获取错误“System.IndexOutOfRangeException”。为什么?

时间:2012-06-07 21:18:15

标签: c# asp.net sql

我有以下Web服务:

using (SqlCommand cmd = new SqlCommand(@"SELECT r.NAME, s.NAME FROM REGION r LEFT OUTER JOIN STADT s ON s.REGION_ID = r.ID ORDER BY r.NAME", con))
{
    con.Open();
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            if (rdr["r.NAME"] != DBNull.Value && rdr["s.NAME"] != DBNull.Value)
            {
                stadtObject.Add(new STADT()
                {
                    RegionName = rdr["r.NAME"].ToString(),
                    StadtName = rdr["s.NAME"].ToString()
                });
            }
        }
    }
}

我在SQL Management Studio中测试了SQL语句,并且像魅力一样工作。但是如果我在浏览器中调用方法,我会收到错误:

System.IndexOutOfRangeException: r.NAME
   at System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName)
   at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name)
   at System.Data.SqlClient.SqlDataReader.get_Item(String name)
   at StadtHelper.Stadt() in C:\Users\Yeah\Documents\Visual Studio 2010\Projects\WebService1\WebService1\StadtHelper.cs:line 31
   at WebService1.Service1.Stadt() in C:\Depp\Ushi\Documents\Visual Studio 2010\Projects\WebService1\WebService1\Service1.asmx.cs:line 77

我不知道我做错了什么。也许你可以帮助我。

提前谢谢。

4 个答案:

答案 0 :(得分:9)

当在DataReader中选择r.Name时,它只读取 字段 名称 - 名称。选择字段时,它不包括表格说明符(r。和s。)

它无法找到" r.Name"或" s.Name"因为在评估时,读者只需返回两列,这两列都命名为" Name"因此,当搜索r.Name时,运行时声称" r.Name不在有效列名列表中#34; (表现在IndexOutOfRange异常中)。

如果您希望能够通过名称访问它,则必须使用AS语句为查询提供结果的内存结果不同的字段名称:

我认为我说的很糟糕,但实质上,您的代码应该这样修改:

using (SqlCommand cmd = new SqlCommand(@"SELECT r.NAME AS rName, s.NAME AS sName FROM REGION r LEFT OUTER JOIN STADT s ON s.REGION_ID = r.ID ORDER BY r.NAME", con))
{
    con.Open();
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            if (rdr["rNAME"] != DBNull.Value && rdr["sNAME"] != DBNull.Value)
            {
                stadtObject.Add(new STADT()
                {
                    RegionName = rdr["rNAME"].ToString(),
                    StadtName = rdr["sNAME"].ToString()
                });
            }
        }
    }
}

答案 1 :(得分:1)

不喜欢别名r,cource会给你一个潜在的问题,因为你的列名不是唯一的。

尝试类似

的内容

Select r.Name as RName, s.Name as SName ...

然后rdr["RName"]rdr["SName"]将成为观众。

答案 2 :(得分:0)

表名不能用于限定SqlDataReader中的字段名称;在您的情况下,字段名称为"NAME"

为避免命名冲突,您应重命名投影中的列:

SELECT r.NAME AS RegionName, s.NAME AS StateName FROM REGION r …

然后,使用新名称访问字段:

if (rdr["RegionName"] != DBNull.Value && rdr["StateName"] != DBNull.Value)

答案 3 :(得分:0)

数据阅读器不知道r.NAME是谁,因为实际返回的列是NAME和NAME。您可以使用别名来区分两者,如下所示:

SELECT r.NAME as REGION_NAME, s.NAME as STADT_NAME FROM REGION r LEFT OUTER JOIN STADT s ON s.REGION_ID = r.ID ORDER BY r.NAME

然后通过别名访问返回的数据:

if (rdr["REGION_NAME"] != DBNull.Value && rdr["STADT_NAME"] != DBNull.Value)
                    {
                        stadtObject.Add(new STADT()
                        {
                            RegionName = rdr["REGION_NAME"].ToString(),
                            StadtName = rdr["STADT_NAME"].ToString()
                        });
                    }