0

私は Web アプリケーションを作成しており、SQL クエリからの値をリスト ボックスに入力し、リスト ボックス内の値の 1 つが選択されたときにテキスト ボックスに入力する最良の方法を知りたいと考えています。それはひどく遅いようです。現在、(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 クエリによるものではなく、DB への接続を開くためのオーバーヘッドによるものだと思います。
    接続管理/プーリング ソリューションを確認することをお勧めします (小さな例。Google には他にもたくさんあります)。

  2. コマンド query( 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 層アーキテクチャも検討します (アプリの大きさによって異なります)。私は本当にプレゼンテーション層でのデータアクセスが好きではありません:)

さらに具体的な質問がある場合は、ここに投稿してください。
コメントや既存のコードを改善する方法を探している場合は、stack exchange にコード レビュー サイトが用意されました。幸運を祈ります。

于 2012-09-07T15:59:10.623 に答える
0

合計データ サイズに応じて、可能なすべての組み合わせをクライアント側にキャッシュして、select 値が変更されたときにテキスト ボックスを更新できるようにすることができます。考えられるすべての組み合わせが、たとえば 300KB 未満の場合、接続の速度によっては、これをクライアント ブラウザーに送信するのが合理的かもしれません。

サーバーへのラウンドトリップを実行してテキストボックスにデータを入力すると、それが即時のフィードバックであることが期待される場合、常に思ったより遅くなります。もちろん、何らかの理由で DB クエリが遅い可能性もありますので、それも調査してください。

その他の考慮事項:

  • これがクライアントとサーバーが同じ LAN 上にある内部アプリの場合、接続速度がさらに速くなることが期待されるため、ユース ケースによっては、さらに大量のデータ (数 MB ?)
  • これが低速または一貫性のない接続を持つアプリの場合は、ニーズとクライアント ブラウザーの機能に応じて、クライアントに送信しようとするデータの量を制限することをお勧めします。あなたがどこから来たのかを理解していれば、最初のページの読み込み時間と、ページが読み込まれた後のページの応答性との間のトレードオフのように思えます (キャッシュされたデータがある場合は、クライアント マシンで利用できます)。
于 2012-09-07T15:56:57.140 に答える