我正在连接到SQL Server 2012数据库,以根据ID查询单个值。 (值得一提的是,这个数据库位于我的开发机器的另一个大陆的服务器上,所以延迟非常高。大约100ms左右。)
查询似乎成功执行。 HasRows
对象的SqlDataReader
属性设置为true,因此我尝试使用该值来分配变量。当我正常运行程序时,遇到消息'Given key was not present in the dictionary'
的异常。如果我停止执行并检查SqlDataReader
对象,并枚举结果。首先我被告知'enumeration yielded no results'
然后当我继续执行时,我得到一个不同的例外,消息'invalid attempt to read when no data is present'
以下是相关代码:
SqlConnection sql_conn = new SqlConnection(ConnectionString);
SqlCommand sql_cmd = new SqlCommand(String.Format("select ItemType from ItemTable where ItemID='{0}'", item_id), sql_conn);
Console.WriteLine(sql_cmd.CommandText);
sql_conn.Open();
SqlDataReader rdr = sql_cmd.ExecuteReader();
rdr.Read();
if (rdr.HasRows) //True
{
item_type= TypesMap[rdr["ItemType"].ToString()]; //Either 'given key not found in dictionary' or 'invalid attempt to read when no data is present'
}
我已在SQL Server Management Studio中执行了SQL语句,但它已成功完成。我尝试将ItemID硬编码到C#代码中的语句中,并且存在相同的错误。
我还可以做些什么来调试这个?在我尝试访问查询结果之前,一切似乎都没问题。
答案 0 :(得分:3)
您必须调试:似乎TypesMap
没有从数据库中读取的密钥:
// Wrap IDisposable into using
using (SqlConnection sql_conn = new SqlConnection(ConnectionString)) {
// Make SQL readable
// Make SQL parametrized (and not formatted) when it's possible
String sql =
@"select ItemType
from ItemTable
where ItemID = @prm_ItemId";
// Wrap IDisposable into using
using (SqlCommand sql_cmd = new SqlCommand(sql, sql_conn)) {
// I don't know ItemID's type that's why I've put AddWithValue
sql_cmd.Parameters.AddWithValue("@prm_ItemId", item_id);
// Wrap IDisposable into using
using (SqlDataReader rdr = sql_cmd.ExecuteReader()) {
// rdr.HasRows is redundant - rdr.Read() returns true if record has been read
if (rdr.Read()) {
String key = Convert.ToString(rdr.GetValue(0));
// Put break point here: what is the "key" value?
item_type = TypesMap[key];
}
}
}
}
编辑:正如Luke在评论中提到的,错误的原因是密钥比较应该是不区分大小写的,所以修正是要解释的。网如何比较键:
var TypesMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
...
TypesMap.Add("aBc", "xyz");
String test = TypesMap["Abc"]; // return "xyz"; notice "aBc" and "Abc"
答案 1 :(得分:2)
正如德米特里指出的那样,没有找到钥匙......&#39;不是数据库的东西,而是字典的东西。 下面我添加了一个简单的检查,以确保密钥在字典中 - 如果是,那么我们可以分配到item_type。
此外,如果HasRows()没有按照您的意愿行事,请尝试以下操作。这是我从DB读取的标准方式:
using (SqlDataReader results = sql_cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
while (results.Read())
{
string Key = rdr["ItemType"].ToString();
if (TypesMap.ContainsKey(Key))
item_type = TypesMap[Key];
}
}
答案 2 :(得分:1)
我转换了:
dto.Id = (int)record["Id"];
要:
dto.Id = (int)record[0];
这对我有用。