![](/img/trans.png)
[英]How can I debug the parameters passed when using an inline sqldatasource?
[英]How can I use SqlDataSource properly with parameters?
这是我正在使用的代码(与oracle开发人员工具一起使用):
<asp:SqlDataSource ID="FirstNameSQL" runat="server" ConnectionString="<%$ ConnectionStrings:UserQueries %>" ProviderName="<%$ ConnectionStrings:UserQueries.ProviderName %>"
SelectCommand="SELECT "FIRSTNAME" FROM "USERS" WHERE ("USERNAME" = '%?')">
<SelectParameters>
<asp:ControlParameter ControlID="UsernameLabel" Name="firstname" PropertyName="Text" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
我想做的是使用标签文本中的参数进行查询。 但是它什么也不会返回。 也许我的数据检索方法错误,在这里:
DataView dv4 = (DataView)FirstNameSQL.Select(DataSourceSelectArguments.Empty);
foreach (DataRow r in dv4.Table.Rows)
{
FirstNameLabel.Text = (string)r[0];
}
有什么建议么?
不应使用SqlDataSource
以编程方式检索数据,而应使用OracleCommand
类。 仅当直接绑定到GridView
或其他控件时,才应使用SqlDataSource
。 实际上,根本不应该使用SqlDataSource
,因为在设计合理的系统中,不应在UI层中进行数据访问。
public static DataTable GetDataTable(OracleCommand command)
{
DataTable dt = new DataTable();
using (var connection = GetDefaultOracleConnection())
{
command.Connection = connection;
connection.Open();
dt.Load(command.ExecuteReader());
}
return dt;
}
public static OracleConnection GetDefaultOracleConnection()
{
return new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); //just get a connection string from somewhere
}
//usage
var command = new OracleCommand("select firstname from users where username=:username");
command.Parameters.Add("username", UsernameLabel.Text.Trim());
command.BindByName = true; //incredibly important if more than one parameter
var dt = GetDataTable(command);
DataView dv = dt.AsDataView();
//now get the results. I prefer getting it from the DataTable instead of DataView. Easier to use Linq
if(dt.Rows.Count > 0)
{
/* Below line requires extra reference to System.Data.DataSetExtensions */
FirstNameLabel.Text = dt.AsEnumerable().First().Select(r => r.Field<string>("firstname"));
}
else
{
FirstNameLabel.Text = "not found";
}
上面的内容已经向您展示了如何以编程方式从数据库中获取数据。 但是它仍然没有遵循好的架构,因为我们在后面的代码中使用了数据库访问代码。 我们后面的代码对数据库实现细节一无所知。 因此,让我们从头开始,为架构师更好一些。 首先,我们应该定义一个包含用户详细信息的类。 我将其命名为ApplicationUser
这样我们就不会与Page.User
属性发生冲突。
public class ApplicationUser
{
public string Username {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
}
太酷了,现在我们已经定义了ApplicationUser所需的内容。 但是我们还需要一种从数据库加载用户的方法。 那不应该在我们后面的代码或模型中发生,而应该在数据层中发生。
public class MySiteOracleRepository
{
private string ConnectionString {get; set;}
public MySiteOracleRepository(string connectionString)
{
ConnectionString = connectionString;
}
public ApplicationUser GetUserByUsername(string username)
{
OracleCommand command = new OracleCommand("select firstname, lastname, username from users where username=:username");
DataTable dt = OracleDatabaseHelper.GetDataTable(command, ConnectionString);
ApplicationUser user = dt.AsEnumerable().Select(r => new ApplicationUser(){
FirstName = r.Field<string>("firstname"),
LastName = r.Field<string>("lastname"),
Username = r.Field<string>("username")
}).Single();
return user;
}
}
那很好。 现在,我们需要实现OracleDatabaseHelper.GetDataTable()
,它将执行对数据库的实际访问。
public class OracleDatabaseHelper
{
public static DataTable GetDataTable(OracleCommand command, string connectionString)
{
DataTable dt = new DataTable();
using (var connection = new OracleConnection(connectionString))
{
command.Connection = connection;
connection.Open();
dt.Load(command.ExecuteReader());
}
return dt;
}
}
现在,这给了我们什么? 一种获取用户信息的简单且可重复使用的方法。 由于有了此代码,因此不需要每次都需要检索用户信息时重复自己,因此遵循DRY(请勿重复自己)原则。 因此,让我们看看我们的页面背后的代码现在看起来是什么样子。
private MySiteOracleRepository repo {get; set;}
protected void Page_Load(object sender, EventArgs e)
{
repo = new MySiteOracleRepository(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
if(!IsPostBack)
{
LoadUserInfo();
}
}
protected void LoadUserInfo()
{
ApplicationUser user = repo.GetUserByUsername(UsernameLabel.Text);
FirstNameLabel.Text = user.FirstName;
LastNameLabel.Text = user.LastName;
}
看看我们的页面变得多么简单? 并注意编写一个新的MySiteMySqlRepository
, MySitePostgresRepository
, MySiteMongoRepository
等非常容易,您只需要真正地创建一个新类即可。 您必须修改页面以使用不同的存储库类型,但是可以通过Dependency Injection解决这个问题。 但是,我不会在这里讨论这个问题,因为我可能会通过足够多的新内容对您进行介绍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.