0

我正在制作一个 Web 应用程序,并且想知道使用 sql 查询中的值填充列表框的最佳方法,然后在选择列表框中的值之一时填充文本框。看起来慢得可怕。目前,我打开一个连接(来自一个 xml 文件)并进行查询,将 SSN 放入列表框中。然后,在 selectedindexchanged 上,重新打开并再次查询(相同的查询)以获取与该 SSN 关联的名称并将这些结果放入文本框中。有没有更好(更快)的方法来做到这一点?这是我目前拥有的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        private SqlConnection Sqlconnection;//= new SqlConnection(ConfigurationManager.ConnectionStrings["xxxConnectionString"].ToString());
        private SqlCommand command;
        private string sqlQuery = "";
        private SqlDataReader reader;
        private static string configFile=@"C:\Documents and Settings\xxx\My Documents\Visual Studio 2010\Projects\WebApplication1\WebApplication1\Config.xml";

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// Get connection info from config.xml
        /// </summary>
        private void ReadConnection()
        {
            string conn = String.Empty;

            //Create xml document
            XmlDocument xmlDoc = new XmlDocument();
            //Load the config file (hard-coded for now)
            xmlDoc.Load(configFile);
            XmlNodeList connection = xmlDoc.GetElementsByTagName("Connection");
            conn = connection[0].InnerText;
            Sqlconnection = new SqlConnection(conn);
            //return conn;
        }

        /// <summary>
        /// Get query from config.xml
        /// </summary>
        /// <returns></returns>
        private string ReadQuery()
        {
            if (string.IsNullOrEmpty(sqlQuery))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(configFile);
                XmlNodeList query = xmlDoc.GetElementsByTagName("Query");
                sqlQuery = query[0].InnerText;
            }

            return sqlQuery;
        }

        /// <summary>
        /// Populates textboxes on listBox index changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ListBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                ReadConnection();
                SqlCommand command = new SqlCommand("SELECT TOP (100) S.PlanID, S.EmployerID, S.VendorID, S.SSN, D.First, D.Middle, D.Last, D.State, S.NumLoans, S.TypeAcct, S.ERBalance, S.YTDEEContrib FROM SparkData AS S WITH(NOLOCK) INNER JOIN Demographics AS D WITH(NOLOCK) ON S.SSN = D.SSN ORDER BY S.SSN", Sqlconnection);
                command = new SqlCommand(ReadQuery(), Sqlconnection);
                Sqlconnection.Open();
                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            //Assign to textbox here
                            if (reader["SSN"].ToString() == ListBox2.SelectedValue)
                            {
                                TextBox1.Text = reader["First"].ToString();
                                TextBox2.Text = reader["Middle"].ToString();
                                TextBox3.Text = reader["Last"].ToString();
                            }
                        }
                    }
            }
            catch (SqlException ex)
            {
                Response.Write(ex.Message.ToString());
            }
            finally
            {
                Sqlconnection.Close();
                SqlConnection.ClearPool(Sqlconnection);
            }
        }

        /// <summary>
        /// Connect to sql and populate listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                ReadConnection();
                command = new SqlCommand(ReadQuery(), Sqlconnection);
                Sqlconnection.Open();
                reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        //Assign SSNs to listbox
                        ListBox2.Items.Add(reader["SSN"].ToString());
                    }
                }
            }
            catch (SqlException ex)
            {
                Response.Write(ex.Message.ToString());
            }
            finally
            {
                Sqlconnection.Close();
                SqlConnection.ClearPool(Sqlconnection);
            }
        }
    }
}

    <%@ Page Title="xxx Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Welcome to ASP.NET!
    </h2>
    <p>
        To learn more about xxx, Inc. <a href="http://www.tsacg.com/" title="xxx Website">www.xxx.com</a>
        <br />
        Here is the <a href="https://xxx-sql38.xxx.com/"
            title="xxx, Inc Intranet Portal">xxx Intranet Portal</a>.
    </p>
    <div align="center">
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Connect" 
            ToolTip="Click to populate the SSN ListBox"/>
    </div>
    <div align="center">
    <asp:ListBox ID="ListBox2" runat="server" AutoPostBack="True" EnableViewState="true"
        onselectedindexchanged="ListBox2_SelectedIndexChanged" Width="200px">
    </asp:ListBox>
    </div>
    <div align="center">
    <asp:TextBox ID="TextBox1" Width="125" runat="server">First Name</asp:TextBox>
    <asp:TextBox ID="TextBox2" Width="25" runat="server">MI</asp:TextBox>
    <asp:TextBox ID="TextBox3" Width="125" runat="server">Last Name</asp:TextBox>
    </div>
    <%--<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:xxxDataConnectionString %>"--%>


    <%--SelectCommand="SELECT TOP (100) S.PlanID, S.EmployerID, S.VendorID, S.SSN, D.First, D.Middle, D.Last, D.State, S.NumLoans, S.TypeAcct, S.ERBalance, S.YTDEEContrib FROM SparkData AS S WITH (NOLOCK) INNER JOIN Demographics AS D WITH (NOLOCK) ON S.SSN = D.SSN ORDER BY S.SSN">
</asp:SqlDataSource>--%>
    <%--<asp:ListBox ID="ListBox1" runat="server" DataSourceID="SqlDataSource1"
            DataTextField="SSN" DataValueField="SSN" Width="200px" EnableViewState="true" AutoPostBack="true"
        onSelectedIndexChanged="ListBox1_SelectedIndexChanged"></asp:ListBox>--%>
    </asp:Content>
4

2 回答 2

0

关于您的代码的一些评论-

  1. 为每个请求打开和关闭连接是非常低效的。我猜您遇到的延迟不是因为 SQL 查询,而是因为打开与数据库的连接的开销。
    您可能想看看连接管理/池解决方案(小例子;谷歌肯定有更多)。

  2. 在初始化您的命令查询 ( SqlCommand command = new SqlCommand("SELECT TOP (100) S.PlanID, S.EmployerID, S.VendorID, S.SSN, D.First, D.Middle, D.Last, D.State, S.NumLoans, S.TypeAcct, S.ERBalance, S.YTDEEContrib FROM SparkData AS S WITH(NOLOCK) INNER JOIN Demographics AS D WITH(NOLOCK) ON S.SSN = D.SSN ORDER BY S.SSN", Sqlconnection);) 后,您立即使用command = new SqlCommand.... 这是为什么?

  3. 继续我的第一句话——在代码中将查询写成字符串既低效又不安全。如果你有时间,我会读一些关于OR/M的文章(我最喜欢的是 nhibernate)
  4. 我还想看看n 层架构(取决于你的应用程序有多大);我真的不喜欢表示层中的数据访问:)

如果您有任何更具体的问题,请随时在此处发布。
如果您正在寻找改进现有代码的评论和方法,堆栈交换现在有一个代码审查站点。祝你好运。

于 2012-09-07T15:59:10.623 回答
0

根据总数据大小,您可以在客户端缓存所有可能的组合,以便当它们更改选择值时,您可以更新文本框。如果所有可能的组合都小于 300KB,那么根据连接速度将其发送到客户端浏览器可能是合理的。

往返于服务器以填充文本框,如果期望它是即时反馈,总是会比你喜欢的要慢。当然,也可能是您的数据库查询由于某种原因很慢,所以也要调查一下。

其他注意事项:

  • 如果这是针对客户端和服务器位于同一 LAN 上的内部应用程序,那么连接速度有望更快,因此根据您的用例,缓存更多数据(几 MB ?)
  • 如果这是针对连接缓慢或不一致的应用程序,同样取决于您的需求和客户端浏览器的功能,最好限制您尝试发送到客户端的数据量。如果我了解您来自哪里,这听起来像是初始页面加载时间和页面加载后的响应能力之间的权衡(并且缓存数据,如果有的话,在客户端计算机上可用)。
于 2012-09-07T15:56:57.140 回答