我正在尝试更改我的代码。我在编写代码的过程中,我的C#/ ASP.Net应用程序的许多部分都使用LINQ to SQL,许多部分使用命令直接访问sql数据库。我觉得我应该标准化这些,所以我正在改变LINQ to SQL代码。我有一部分代码根据会话变量获取找到一条记录,然后用sql查询结果填充我标题中的标签。这是代码:
protected void Page_Load(object sender, EventArgs e)
{
var pinNum = MySession.Current.focusParcel;
if (pinNum != 0)
{
String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;
SqlConnection connection = new SqlConnection(sql);
connection.Open();
SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM[ParcelView] WHERE PARCEL = " + pinNum, connection);
SqlDataReader selectedParcel = command.ExecuteReader();
if (selectedParcel != null)
{
lblPIN_Num.Text = selectedParcel["PARCEL"].ToString();
lblPIN_TXT.Text = selectedParcel["PIN_TXT"].ToString();
lblDateTime.Text = DateTime.Now.ToString("MMMM dd, yyyy");
lblOwner.Text = selectedParcel["Owner"].ToString();
lblAddress1.Text = selectedParcel["Address1"].ToString();
lblAddress2.Text = selectedParcel["Address2"].ToString();
lblCSZ.Text = selectedParcel["CSZ"].ToString();
lblAcres.Text = string.Format("{0} Acres", selectedParcel["ACRES"]);
lblLegal.Text = selectedParcel["LEGAL"].ToString();
if (selectedParcel["Active"].ToString() == "A")
{
lblInactive.Text = " (ACTIVE)";
}
else
{
lblInactive.Text = " (INACTIVE)";
lnkAddDocument.Visible = false;
}
}
lblCurrentUser.Text = Page.User.Identity.Name;
connection.Close();
}
else
Response.Redirect("./ParcelSearch.aspx");
}
我收到以下错误:
没有数据时无效尝试读取。
我知道使用的SQL语句在直接用于数据库的sql查询时会返回一条记录。
提前感谢任何建议。我是否应该关注在整个应用程序中访问数据时缺乏一致性?如果是这样,我应该将所有内容转换为LINQ吗?或者将所有内容从LINQ转换出来?我知道MVC的存在并且知道我应该学习并使用它,但是我现在试图转换它的路径太远了。
答案 0 :(得分:1)
更改
if (selectedParcel != null)
到
if (selectedParcel.Read())
在开始提取数据之前,您必须先读取数据读取器中的记录。它是一个仅向前游标,开始时不指向记录。 Read()
方法使读者前进1,如果成功则返回true / false。
请注意,如果使用上述代码,则无需致电HasRows
。只有在有行的情况下才会输入if块,如果没有则返回,则返回false并且不输入该块。
您的代码中存在许多不良做法。
Sql代码更改
String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;
using(SqlConnection connection = new SqlConnection(sql))
using(SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM [ParcelView] WHERE PARCEL = @pinNum", connection))
{
command.Parameters.Add(new SqlParameter("@pinNum", SqlDbType.VarChar){Value = pinNum});
connection.Open();
using(SqlDataReader selectedParcel = command.ExecuteReader())
{
if (selectedParcel.Read())
{
/*code unchanged*/
}
}
/* 1 line code unchanged*/
}
答案 1 :(得分:0)
执行完命令后,您需要实际读取数据:
SqlDataReader selectedParcel = command.ExecuteReader();
if (selectedParcel.HasRows)
{
selectedParcel.Read();
....
....
答案 2 :(得分:0)
您应该Read()
SqlDataReader
。
protected void Page_Load(object sender, EventArgs e)
{
var pinNum = MySession.Current.focusParcel;
if (pinNum == 0)
Response.Redirect("./ParcelSearch.aspx");
String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;
using(SqlConnection connection = new SqlConnection(sql))
{
connection.Open();
SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM[ParcelView] WHERE PARCEL =@PinNum ", connection);
//protect from sql injection
command.Parameters.AddWithValue(@PinNum, pinNum);
using(SqlDataReader selectedParcel = command.ExecuteReader())
{
if(!selectedParcel.HasRows)
return;
SetLabels(selectedParcel);
}
}
}
private void SetLabels(SqlDataReader selectedParcel)
{
lblPIN_Num.Text = selectedParcel["PARCEL"].ToString();
lblPIN_TXT.Text = selectedParcel["PIN_TXT"].ToString();
lblDateTime.Text = DateTime.Now.ToString("MMMM dd, yyyy");
lblOwner.Text = selectedParcel["Owner"].ToString();
lblAddress1.Text = selectedParcel["Address1"].ToString();
lblAddress2.Text = selectedParcel["Address2"].ToString();
lblCSZ.Text = selectedParcel["CSZ"].ToString();
lblAcres.Text = string.Format("{0} Acres", selectedParcel["ACRES"]);
lblLegal.Text = selectedParcel["LEGAL"].ToString();
if (selectedParcel["Active"].ToString() == "A")
{
lblInactive.Text = " (ACTIVE)";
}
else
{
lblInactive.Text = " (INACTIVE)";
lnkAddDocument.Visible = false;
}
lblCurrentUser.Text = Page.User.Identity.Name;
}
我重构你的代码看起来有点像。你有不同的问题,因为没有关闭你的阅读器。你对sql注入是开放的,你也应该在单独的类中将连接转移到Db。
答案 3 :(得分:0)
我建议您将此格式用于sqlDatareader,因为它将解析是否已检索到结果,并将自动处理异常:
using(SqlDataReader selectedParcel = command.ExecuteReader())
{
while (selectedParcel .Read())
{
//Assign label text to results
}
}