2016-03-22 5 views
1

auto complete Textbox mit Oracle-Datenbank (Improvement)

aktualisiert
public class PopulateProduct 
    { 
     public string ProductDesc { get; set; } 
     public decimal UnitPrice { get; set; } 
    } 

    Dictionary<string, PopulateProduct> dict = new Dictionary<string, PopulateProduct>(); 

    public void load() 
    { 
     string connstr = "user id=rawpic;password=admin"; 
     string cmdtxt = @"select PRODUCT_ID,DESCRIPTION,UNIT_PRICE 
           from products"; 

     AutoCompleteStringCollection autocom = new AutoCompleteStringCollection(); 
     TB_PRODUCT_ID.AutoCompleteMode = AutoCompleteMode.Suggest; 
     TB_PRODUCT_ID.AutoCompleteSource = AutoCompleteSource.CustomSource; 
     TB_PRODUCT_ID.AutoCompleteCustomSource = autocom; 

     using (OracleConnection conn = new OracleConnection(connstr)) 
     using (OracleCommand cmd = new OracleCommand(cmdtxt, conn)) 
     { 
      try 
      { 
       conn.Open(); 
       OracleDataReader dr = cmd.ExecuteReader(); 

       while (dr.Read()) 
       { 
        dict.Add((string)dr["PRODUCT_ID"], 
         new PopulateProduct() 
         { 
          ProductDesc = (string)dr["DESCRIPTION"], 
          UnitPrice = (decimal)dr["UNIT_PRICE"] 
         }); 
        autocom.Add(dr["PRODUCT_ID"].ToString()); 
       } 

      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message,"",MessageBoxButtons.OK,MessageBoxIcon.Error); 
      } 
     } 
    } 


    private void TB_PRODUCT_ID_TextChanged(object sender, EventArgs e) 
    { 
     if (dict.ContainsKey(TB_PRODUCT_ID.Text)) 
     { 
      TB_PRODUCTS_DESC.Text = dict[TB_PRODUCT_ID.Text].ProductDesc; 
      TB_UNIT_PRICE.Text = dict[TB_PRODUCT_ID.Text].UnitPrice.ToString(); 
     } 
    } 

------ Alte Skript unten -------

Ich bin Unter Verwendung von Code zur automatischen Vervollständigung textbox Wertdaten dann automatisch den Wert von zwei weiteren textboxs Produktbeschreibung ändern a nd Preis der Code unten funktioniert gut, aber die Beschreibung textbox Wert nicht korrekt ist es den letzten Datensatz Datenbankwert bekommen, so dass jeder Vorschlag darüber?

endlich gibt es einen schnelleren Weg zur Auto-Vervollständigung ??

Notiz ist nicht notwendig, Beschreibung und Preis textbox mit Produkt-ID synchronisieren zu aktualisieren sofort kann es nach Benutzern wählen Sie die Produkt-ID wie bei der Auswahl passieren, wenn das möglich und schneller bitte mir sagen, wie

private void TB_PRODUCT_ID_TextChanged(object sender, EventArgs e) 
    { 
     string connstr = "user id=rawpic;password=admin"; 
     string cmdtxt = @"select PRODUCT_ID,DESCRIPTION,UNIT_PRICE 
           from products"; 

     AutoCompleteStringCollection autocom = new AutoCompleteStringCollection(); 
     TB_PRODUCT_ID.AutoCompleteMode = AutoCompleteMode.Suggest; 
     TB_PRODUCT_ID.AutoCompleteSource = AutoCompleteSource.CustomSource; 
     TB_PRODUCT_ID.AutoCompleteCustomSource = autocom; 

     using (OracleConnection conn = new OracleConnection(connstr)) 
     using (OracleCommand cmd = new OracleCommand(cmdtxt, conn)) 
     { 
      try 
      { 
       conn.Open(); 
       OracleDataReader dr = cmd.ExecuteReader(); 
       while (dr.Read()) 
       { 
        autocom.Add(dr["PRODUCT_ID"].ToString()); 
        TB_PRODUCTS_DESC.Text = dr["DESCRIPTION"].ToString(); 
       } 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 
    } 

ich habe müde Parameter für die select-Anweisung hinzuzufügen, bei denen ein Teil als unten, aber das wird nicht funktionieren

 private void TB_PRODUCT_ID_TextChanged(object sender, EventArgs e) 
    { 
     string connstr = "user id=rawpic;password=admin"; 
     string cmdtxt = @"select PRODUCT_ID,DESCRIPTION,UNIT_PRICE 
           from products 
          where PRODUCT_ID=:PRODUCTID"; 

     AutoCompleteStringCollection autocom = new AutoCompleteStringCollection(); 
     TB_PRODUCT_ID.AutoCompleteMode = AutoCompleteMode.Suggest; 
     TB_PRODUCT_ID.AutoCompleteSource = AutoCompleteSource.CustomSource; 
     TB_PRODUCT_ID.AutoCompleteCustomSource = autocom; 

     using (OracleConnection conn = new OracleConnection(connstr)) 
     using (OracleCommand cmd = new OracleCommand(cmdtxt, conn)) 
     { 
      try 
      { 
       conn.Open(); 
       OracleDataReader dr = cmd.ExecuteReader(); 
       while (dr.Read()) 
       { 
        autocom.Add(dr["PRODUCT_ID"].ToString()); 
        cmd.Parameters.Add(new OracleParameter("PRODUCTID", TB_PRODUCT_ID.Text)); 
        TB_PRODUCTS_DESC.Text = dr["DESCRIPTION"].ToString(); 
       } 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 
    } 
+0

Die erste Abfrage hat keine 'WHERE'-Klausel, weshalb sie nicht richtig funktioniert. Ihre zweite Abfrage tut das, aber Sie haben uns nicht gesagt, warum es "nicht funktioniert". Können Sie mehr Details angeben? –

+0

Mit AutoCompleteStringCollection müssen Sie nicht ständig requery! Initialisieren Sie die Sammlung einfach mit ALLEN Wörtern, und .NET übernimmt die Filterung der Vorschläge, wenn der Benutzer schreibt. Das sollte dein Geschwindigkeitsproblem verschwinden lassen ... – SlimsGhost

Antwort

1

Sie sind nur eine Liste aus dem PRODUCT_ID Ergebnis der Anfrage bevölkern. Der erste Beispielcodeblock zeigt, dass Sie eine AutoCompleteStringCollection aktualisieren, aber die Beschreibung, die Sie gerade überschreiben, das statische Textfeld mit dem letzten Element in der Schleife enthält.

Außerdem führen Sie diesen schweren Code jedes Mal aus, wenn sich der Text ändert, das muss wirklich träge sein. Das zweite Beispiel funktioniert nicht, da Sie ein Element in die Parametersammlung einfügen, aber wie in einem Verwendungsblock, der beim Abschluss der Schleife entsorgt wird (Sie würden die Parameter auf diese Weise sowieso nicht verwenden).

Ein Vorschlag wäre, ein Wörterbuch des Typs zu erstellen und das in Ihrer Schleife zu füllen. Wenn sich Ihr Textfeld ändert, können Sie das Wörterbuch [PRODUCT_ID] .Description und .Price verwenden - dies würde die Geschwindigkeit beim Ausführen der Anwendung erhöhen, da Sie nicht jedes Mal zur Datenbank zurückkehren würden.

public class MyObject { 
    string Description {get;set;} 
    decimal UnitPrice {get;set;} 
} 

public Dictionary<string, MyObject> _dict = new Dictionary<string, MyObject>(); 

public void Load() 
{ 
    string connstr = "user id=rawpic;password=admin"; 
    string cmdtxt = @"select PRODUCT_ID,DESCRIPTION,UNIT_PRICE from products"; 

    AutoCompleteStringCollection autocom = new AutoCompleteStringCollection(); 
    TB_PRODUCT_ID.AutoCompleteMode = AutoCompleteMode.Suggest; 
    TB_PRODUCT_ID.AutoCompleteSource = AutoCompleteSource.CustomSource; 
    TB_PRODUCT_ID.AutoCompleteCustomSource = autocom;  

    using (OracleConnection conn = new OracleConnection(connstr)) 
    using (OracleCommand cmd = new OracleCommand(cmdtxt, conn)) 
    { 
     try 
     { 
      conn.Open(); 
      OracleDataReader dr = cmd.ExecuteReader(); 
      while (dr.Read()) 
      { 
       _dict.Add(dr["PRODUCT_ID"], new MyObject() { Description = dr["DESCRIPTION"], UnitPrice = dr["UNIT_PRICE"] }; 
       autocom.Add(dr["PRODUCT_ID"].ToString()); 
      } 
     } 
     catch(Exception ex) 
     { 
      // handle exception 
     } 
    } 
} 

private void TB_PRODUCT_ID_TextChanged(object sender, EventArgs e) 
{ 

if (_dict.ContainsKey(TB_PRODUCT_ID.Text)) 
    { 
     TB_PRODUCTS_KEY.Text = _dict[TB_PRODUCT_ID.Text].Description; 
     TB_UNIT_PRICE.Text = _dict[TB_PRODUCT_ID.Text].UnitPrice.ToString(); 
    } 
} 

Wie ich sage, ein Weg, dies zu erreichen, aber ohne dass die anderen Code schwer zu sagen, wenn sie die beste Art und Weise zu sehen.

+0

danke für die sehr nützliche Wiederholung und deine Erklärungen ... Ich hatte deinen Vorschlag gelesen und versucht, aber ich bekam einen Fehler bei dieser Zeile '_dict.Add (dr [" PRODUCT_ID "]), new Object() {ProductDesc = dr ["BESCHREIBUNG"], UnitPrice = dr ["UNIT_PRICE"]}; ' – samer

+0

Die beste überladene Methodenübereinstimmung für 'System.Collections.Generic.Dictionary . Add (string, MyProject.Form.Object) 'hat einige ungültige Argumente Argument 1: kann nicht von' Objekt 'in' Zeichenfolge 'konvertieren ' MyProject.Form1.Object.ProductDesc 'ist aufgrund seines Schutzlevels nicht erreichbar.' MyProject.Form1.Object.UnitPrice 'ist aufgrund seines Schutzlevels \t .... nicht erreichbar. Ich denke, diese Fehler, weil ich die Klasse im falschen Abschnitt definiere, habe ich im Internet überprüft über C# neue Klasse definieren? und nach dem Namensraum definiert, aber ich konnte das Schlüsselwort Dictionary nicht verwenden – samer

+0

Ich lege die Klasse in die Formularklasse und der ganze Code funktioniert gut außer dem Fehler, den ich dir erzählt habe .... Ich denke auch, dass etwas nicht stimmt Schließen der Klammern oder etwas, das diese Fehler verursacht habe ich versucht, sie zu lösen, aber ich fülle .. bitte Ihre Hilfe – samer