SqlDataSource的更好解决方案

本文关键字:解决方案 更好 SqlDataSource | 更新日期: 2023-09-27 18:20:38

我需要在网站的几个页面上显示SQL Server数据库视图中的一些数据。我在web.config中使用了SqlDataSource,然后在.aspx页面中使用了一个GridView控件来显示数据。

现在,这是有效的,但我在一些论坛上读到,使用SqlDataSource是不好的做法?我可能需要管理员/用户在未来过滤数据,所以我不确定这将如何与我当前的实现一起工作。

到目前为止,我的代码如下:

web.config文件中:

<connectionStrings>
    <add name="Test1.ConnectionString" 
         connectionString="Data Source=...."
         providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
</system.web>

在我的aspx 中有这样的东西

<body id="wrap" >
  <form  runat="server">
    <asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" 
         BackColor="White" BorderColor="#CCCCCC" 
         BorderStyle="None" BorderWidth="1px" CellPadding="3" 
         DataSourceID="SqlDataSource1" Height="500px" Width="408px">
        <Columns>
            <asp:BoundField DataField="Title" HeaderText="Title" ReadOnly="True" SortExpression="Title">
                <ItemStyle Width="400px" HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
            </asp:BoundField>
            <asp:BoundField DataField="Result" HeaderText="Result" ReadOnly="True" SortExpression="Result" >
                <ItemStyle HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
            </asp:BoundField>
        </Columns>
        <FooterStyle BackColor="White" ForeColor="#002756" />
        <HeaderStyle BackColor="#003466" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="White" ForeColor="#002756" HorizontalAlign="Left" />
        <RowStyle ForeColor="#002756" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
         ConnectionString="<%$ ConnectionStrings: Test1.ConnectionString %>" 
         SelectCommand="SELECT * FROM [Test1.ConnectionString]"> 
    </asp:SqlDataSource>
  </form>
</body>

所以我的问题是,有没有更好的方法来实现这一点,请记住,我可能需要一个功能,让用户/管理员根据某些标准过滤数据?

SqlDataSource的更好解决方案

使用SqlDataSource并不一定是坏习惯。。。但它确实倾向于将数据访问代码与演示代码混合在一起。此外,使用ObjectDataSource包装视图通常可以做得更好。还有更多的代码(你必须在某个地方创建一个新的类来从你的视图中进行选择),但你最终会得到一些方法,这些方法在未来可以很容易地更新或替换,以处理你可能需要的任何更改。

正如我在评论中提到的,我建议您使用后面的代码来实现这一点,因为如果将来需要,可以更容易地进行更改。我假设您的数据库中有一个名为Test1的表。我们将首先在C#中创建一个类来表示这一点,并添加一些稍后将使用的属性

public class Test
{
  public string Title { get; set; }
  public int Result { get; set; }
}

现在,让我们创建一个方法,从数据库中返回一组值。

public List<Test> GetData()
{
    List<Test> myList = new List<Test>();
    string sqlQuery = "Select Title, Result From Test";
    string connectionString = ConfigurationManager.ConnectionStrings["Test1.ConnectionString"].ConnectionString; //Read connection string from config file
    using (var con = new SqlConnection(connectionString))
    {
        using (var cmd = new SqlCommand(sqlQuery, con))
        {
            //Add param here if required.
            con.Open(); //Open connection
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    Test t = new Test();
                    t.Title = reader["Title"].ToString();
                    t.Result = Convert.ToInt32(reader["Result"]);
                    myList.Add(t);
                }
            }
        }
    }
    return myList;
}

最后,您需要为GridView设置数据源。我假设您有一个名为MyGridPage.aspx的页面,打开MyGridPage.asps.cs,在Page_Load事件中,您可以将网格的DataSource设置为:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        Test t = new Test();
        GridView1.DataSource = t.GetData();
        GridView1.DataBind();
    }
}

如果你想通过例如用户名来过滤你的Sql查询,你会把它改为:

string sqlQuery = "Select Title, Result From Test Where username = @username";

然后您可以将@username参数传递为:

cmd.Parameters.Add("@username", SqlDbType.NVarChar).Value = myUsername;

myUsername可以是登录到你的应用程序的人。您将在打开连接之前传递参数。传递参数还可以防止sql注入,我建议您在不知情的情况下仔细阅读。

注:建议使用using块,以确保连接对象关闭并正确处理。

您可以通过编程设置网格视图的数据源。

    protected void Page_Load(object sender, EventArts e)
    {
        using(SqlConnection conn = new SqlConnection(connectionString))
        {
            string query = "SELECT * FROM Test"; //your SQL query goes here
            SqlCommand cmd = new SqlCommand(query, conn);
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable table = new DataTable();
            da.Fill(table);
            GridView1.DataSource = table;
            GridView1.DataBind();
            cmd.Dispose();
            da.Dispose();
        }
    }