我有以下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
我不知道我做错了什么。也许你可以帮助我。
提前谢谢。
答案 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()
});
}