更好的SqlDataSource解决方案?

时间:2015-11-05 16:05:52

标签: c# sql asp.net sql-server datasource

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

现在,这有效,但我在一些论坛中读到,使用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>

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

正如我在评论中提到的,我建议您使用后面的代码来实现这一点,因为如果将来需要更改它会更容易。我假设你的数据库中有一个名为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块来确保连接对象已正确关闭和处理。

答案 2 :(得分:0)

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

    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();
        }
    }