2012-09-07 27 views
0

我正在製作一個Web應用程序,並希望知道從sql查詢中填充列表框的最佳方式,然後在選擇列表框中的某個值時填充文本框。看起來很慢。目前,我打開一個連接(從XML文件)和查詢,將SSN放入列表框中。然後,在selectedindexchanged上重新打開並重新查詢(相同的查詢)以獲取與該SSN相關聯的名稱,並將這些結果放入文本框中。有沒有更好(更快)的方法來做到這一點?下面是我目前擁有的代碼:根據總數據大小我應該如何正確地從Web應用程序查詢SQL?

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 [email protected]"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> 

回答

0

,您可以緩存在客戶端上的所有可能的組合,這樣,當他們改變選擇值你可以更新文本框。如果所有可能的組合都小於300KB,那麼根據連接的速度將其發送到客戶端瀏覽器可能是合理的。

做一個往返服務器來填充文本框,如果期望它是即時反饋,總是會比你想象的要慢。當然,也可能是因爲某種原因你的數據庫查詢速度很慢,所以也要調查一下。

其他注意事項:

  • 如果這是一個內部應用程序在客戶端和服務器在同一個局域網上,則連接速度將有望再快,所以它可能是合理的,這取決於你用於緩存更大量的數據(幾MB?)
  • 如果這適用於連接速度較慢或不一致的應用程序,再次根據您的需要和客戶端瀏覽器的功能,最好限制您嘗試發送給客戶端的數據量。如果我明白你來自哪裏,這聽起來像是在加載頁面(和客戶機上可用的緩存數據,如果有的話)之間的初始頁面加載時間和頁面響應性之間的折衷。
+0

我如何緩存客戶端的所有組合?你有一些代碼或例子嗎? –

+0

每次我在列表框中選擇不同的項目時,需要4或5秒。我做了一個桌面應用程序來做到這一點,我把整個數據集放入列表框,然後只顯示SSN。這讓我已經擁有了名字的數據。我可以和我如何在Web應用程序中執行此操作? –

+0

這並不是一件快速的事情,但是這裏有一些閱讀材料可以從多個角度來涵蓋主題:http://msdn.microsoft.com/en-us/library/hh404101.aspx - 也可以搜索* *「緩存數據客戶端JavaScript」**其他資源 – jefflunt

0

關於你的代碼 -

  1. 打開和關閉連接爲每個請求一些意見是非常低效的。我猜想你遇到的滯後不是因爲SQL查詢,而是因爲打開到DB的連接的開銷。
    你可能想看看連接管理/池化解決方案(small example;谷歌肯定有更多)。

  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-tiered architecture(取決於你的應用程序的大小);我真的不喜歡錶示層中的數據訪問:)

如果您有任何更具體的問題隨時發佈在這裏。
如果您正在尋找改進現有代碼的意見和方法,堆棧交換現在有code review site。 祝你好運。

+0

2.謝謝,我擺脫了我第一次提出查詢的行。 –

+0

好吧,我讀了這篇文章,這是有道理的。你能告訴我如何在我的例子中實際實現這個?謝謝! –

相關問題