在定义的 While 之外使用类
Posted
技术标签:
【中文标题】在定义的 While 之外使用类【英文标题】:Using class outside of While where it is defined 【发布时间】:2013-01-16 21:11:59 【问题描述】:我试图让我的应用程序检查我的 SQL 数据库中的 Admins 表,然后获取当前用户所属部门的名称。之后,我想检查另一个表并仅选择属于该部门的新闻项目。
下面显示了我将如何处理它,但是问题在于在 While 循环(在第二个 SQL 查询中使用)之外使用 mydepartment 变量。
除此之外一切正常。任何帮助将不胜感激。
public string username = System.Web.HttpContext.Current.User.Identity.Name.Split('\\')[1];
public string mydepartment;
protected void Page_Load(object sender, EventArgs e)
lblUser.Text = username.ToString();
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFileName=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True";
myConnection.Open();
string selectretrieveSQL = ("SELECT * FROM Admins WHERE userid = '" + username.ToString() + "'");
SqlCommand retrieveinfocmd = new SqlCommand(selectretrieveSQL, myConnection);
SqlDataReader reader = retrieveinfocmd.ExecuteReader();
while (reader.Read())
ListItem newItem = new ListItem();
newItem.Text = reader["Department"].ToString();
newItem.Value = reader["userid"].ToString();
UserIds.Items.Add(newItem);
mydepartment = reader["Department"].ToString();
mydepartmentlbl.Text = reader["Department"].ToString();
reader.Close();
string selectNewsSQL = ("SELECT * FROM NewsItems WHERE Department = '" + mydepartment + "'");
【问题讨论】:
你不说它是怎么不工作的。 我清理了代码格式,看起来mydepartment
应该可以正常工作,如果该用户名实际上有任何数据。
另外,一些 cmets:不要那样做 SQL。使用参数化 SQL。特别是对于基于网络的东西,但作为一般来说,总是使用参数。不要连接字符串。这只是等待发生的 SQL 注入。此外,您在 3 个地方执行 reader["Department"].ToString()。执行一次,将其存储在一个变量中并使用该变量。 reader[""] 在性能方面会花费更多。最后,对于您的 SQL 对象,使用 using 关键字。它们是一次性的,不会被丢弃。
另外,mydepartment
是一个字符串变量,而不是一个类。
一个用户是否可以属于多个部门,即数据库查询是保证总是只返回一行,还是可以返回多行?
【参考方案1】:
首先,我强烈建议您创建一些类来保存数据库对象的属性。
例如,您的 Admin 可能如下所示:
public class Admin
public string Username get; set;
public string Department get; set;
// .. More properties here
接下来,您应该创建一些方法来为您完成繁琐的工作。我将从数据库初始化开始:
static SqlConnection InitializeDatabase(string connectionString)
var connection = new SqlConnection(connectionString);
connection.Open();
return connection;
所以也许您有一个方法可以为您获取正确的Admin
:
static IEnumerable<Admin> GetAdminsByUsername(SqlConnection connection,
string username)
var adminList = new List<Admin>();
// You really should be using stored procedures here instead...
var query = @"SELECT * FROM Admins WHERE Username = @Username";
using (var command = new SqlCommand(query, connection))
command.Parameters.AddWithValue("@Username", username);
using (var reader = command.ExecuteReader())
while (reader.Read())
var adminUsername = reader["Username"].ToString();
var adminDepartment = reader["Department"].ToString();
var admin = new Admin
Username = adminUsername,
Department = adminDepartment
;
adminList.Add(admin);
reader.Close();
return adminList;
那么您的Page.Load
可能如下所示:
protected void Page_Load(object sender, EventArgs e)
var connectionString = @"Data Source=.\SQLEXPRESS;AttachDbFileName=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True";
using(var connection = InitializeDatabase(connectionString))
var admin = GetAdminsByUsername(connection, username).FirstOrDefault();
if(admin == null)
// No admin was found, do something here.
return;
var newItem = new ListItem();
newItem.Text = admin.Department.
newItem.Value = admin.Username;
// Keep your controls named consistently, don't use shorthands
// since you already have IntelliSense to auto-complete them for you
usernameLabel.Text = admin.Username;
departmentLabel.Text = admin.Department;
这至少应该让你朝着正确的方向开始。
【讨论】:
【参考方案2】:撇开之前发帖者所说的一切,我都同意,所提供的代码将不起作用,因为在那个 while 循环期间,您所做的是用用户信息填充列表框或某种下拉列表(Department 作为 Display,Userid 作为 value)。
如果您希望能够再根据部门获取更多信息,则需要处理该列表框或选择的 SelectedIndexChanged 事件(或类似事件),获取当前选择的文本值并然后创建第二个查询并执行它。
但是;请务必遵循以前海报的建议,您不必使用存储过程,但您确实应该在查询中使用参数。想象一下,如果某个讨厌的人设法通过 l33t';drop table Admins 的 UserID 会发生什么。然后您的页面将执行以下操作:
SELECT * FROM Admins WHERE userid = 'l33t';drop table Admins;
哎呀....我知道在您的具体情况下您不接受用户输入,但迟早您会...
希望这会有所帮助。
【讨论】:
以上是关于在定义的 While 之外使用类的主要内容,如果未能解决你的问题,请参考以下文章