2009-06-25 17 views
1

Ich habe ein Textfeld, Kombinationsfeld, Schaltfläche und DataGridView auf einem Formular, das zum Suchen und Zurückgeben von Kundeninformationen aus einer MSSQL-Ansicht (vCustomer) verwendet wird. Es funktioniert großartig, aber ich weiß, dass mein Code effizienter sein kann. Die vier Elemente in der Combobox stellen Spalten dar, die gesucht werden sollen.Dynamische Linq To Sql mit ComboBox und Column.Contains

Gibt es eine einfache Möglichkeit zur Umwandlung der folgenden in dynamische LINQ to SQL? Ich bin neu in C#. Ich habe ein paar andere Posts ausgecheckt, aber ich kann es nicht funktionieren sehen.

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    private void MainForm_Load(object sender, EventArgs e) 
    { 
     // columns to filter for 
     string[] list = new string[4]; 
     list[0] = "Name"; 
     list[1] = "CustomerAccountNo"; 
     list[2] = "Telephone"; 
     list[3] = "Postal"; 

     // bind to combobox 
     cboColumn.DataSource = list; 
     cboColumn.SelectedIndex = 0; 
    } 

    private void btnSearch_Click(object sender, EventArgs e) 
    { 

     try 
     { 
      Cursor.Current = Cursors.WaitCursor; 
      CustomerSearchDataContext db = new CustomerSearchDataContext(); 
      IEnumerable<vCustomer> customerQuery = null; 
      switch (cboColumn.SelectedIndex) 
      { 
       case 0: 
        customerQuery = from c in db.vCustomers 
            where c.Name.Contains(txtSearch.Text) 
            orderby c.CustomerAccountNo descending 
            select c; 
        break; 
       case 1: 
        customerQuery = from c in db.vCustomers 
            where c.Name.Contains(txtSearch.Text) 
            orderby c.CustomerAccountNo descending 
            select c; 
        break; 
       case 2: 
        customerQuery = from c in db.vCustomers 
            where c.Telephone.Contains(txtSearch.Text) 
            orderby c.CustomerAccountNo descending 
            select c; 
        break; 
       case 3: 
        customerQuery = from c in db.vCustomers 
            where c.Postal.Contains(txtSearch.Text) 
            orderby c.CustomerAccountNo descending 
            select c; 
        break; 
      } 
      customerBindingSource.DataSource = customerQuery; 
      dataGridView1.DataSource = customerBindingSource; 
      dataGridView1.Columns["CustomerId"].Visible = false; 
     } 
     catch (System.Data.SqlClient.SqlException ex) 
     { 
      MessageBox.Show("An Error Occured - " + ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
     finally 
     { 
      Cursor.Current = Cursors.Default; 
     } 
    } 
} 

Antwort

2

Verwenden Sie [System.Linq.Dynamic][1].

Rufen Sie die Bedingung von einer Methode ab und verwenden Sie sie in einer einzigen Abfrage.

switch (choice) 
    { 
     case case1: 
      condition = string.Format("{0}.Contains({1})", "Column", "Value" 
      break; 
+0

fand ich eine Datei Dynamic.cs innerhalb der CSharpSamples Dateien genannt. Diese Datei hat den richtigen Namensraum - meinst du das? Ich werde es ausprobieren. – robnardo

+0

ja Dynamic.cs hat die Dynamic Linq-Bibliothek – Rony

0

Hallo Rony. Ich habe deinen Vorschlag ausprobiert und meinen Code überarbeitet (siehe unten). Ich erhalte jedoch einen Fehler: Keine Eigenschaft oder Feld "Smith" existiert in Typ "vCustomer". Übrigens, die MessageBox.Show (Bedingung); Zeile gibt Name.Contains (Smith), die korrekt aussieht.

Was mache ich falsch? Sorry für ein Noob und danke für Ihre Hilfe.

Es herausgefunden ... benötigt, um Suchzeichenfolge mit doppelten Anführungszeichen zu umbrechen! Code wurde bearbeitet.

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     InitializeComponent(); 
    } 
    private void MainForm_Load(object sender, EventArgs e) 
    { 
     // data column to filter against 
     string[] list = new string[4]; 
     list[0] = "Name"; 
     list[1] = "CustomerAccountNo"; 
     list[2] = "Telephone"; 
     list[3] = "Postal"; 
     cboColumn.DataSource = list; 
     cboColumn.SelectedIndex = 0; 

     // left, right or middle search 
     string[] list2 = new string[3]; 
     list2[0] = "Contains"; 
     list2[1] = "StartsWith"; 
     list2[2] = "EndsWith"; 
     cboFilterAtt.DataSource = list2; 
     cboFilterAtt.SelectedIndex = 0; 
    } 

    private void btnSearch_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      Cursor.Current = Cursors.WaitCursor; 
      CustomerSearchDataContext db = new CustomerSearchDataContext(); 
      //string condition = string.Format("{0}.{1}({2})", cboColumn.SelectedValue, cboFilterAtt.SelectedValue, txtSearch.Text); 
      string condition = string.Format("{0}.{1}({2})", cboColumn.SelectedValue, cboFilterAtt.SelectedValue, "\"" + txtSearch.Text + "\""); 
      MessageBox.Show(condition); 
      var customerQuery = db.vCustomers.Where(condition).OrderBy("CustomerAccountNo"); 
      customerBindingSource.DataSource = customerQuery; 
      dataGridView1.DataSource = customerBindingSource; 
      dataGridView1.Columns["CustomerId"].Visible = false; 
     } 
     catch (System.Data.SqlClient.SqlException ex) 
     { 
      MessageBox.Show("An Error Occured - " + ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
     finally 
     { 
      Cursor.Current = Cursors.Default; 
     } 
    } 
} 
+0

Oh Mann ... wenn ich "Smith" in das Suchfeld eingeben, funktioniert es. Also, ich denke, ich füge einfach doppelte Anführungszeichen um meine Suchzeichenfolge hinzu und es wird für alle funktionieren! Ich habe "o'rei" versucht und es hat funktioniert! Ich werde meinen Code aktualisieren. Ich änderte, txtSearch.Text) zu "\ txtSearch.Text +" \ "") und es funktioniert! – robnardo

+0

Hinweis, dies funktioniert nicht, wenn die Spalte vom Typ Integer ist. Die Anführungszeichen müssen entfernt werden, wenn die Spalte vom Typ Int ist. Gibt es eine Möglichkeit zu überprüfen, was der Spaltentyp zuerst ist? – robnardo