Dynamische Linq Mit ComboBox und Column.Contains auf SQL
-
20-08-2019 - |
Frage
Ich habe ein Textfeld, Kombinationsfeld, Knopf und Datagridview auf einem Formular, das zu suchen und Kundeninformationen aus einer MSSQL-Ansicht (vCustomer) zurückzukehren verwendet wird. Es funktioniert großartig, aber ich weiß, dass mein Code effizienter sein kann. Die vier Elemente in der Combobox repräsentieren Spalten zu suchen.
Gibt es eine einfache Möglichkeit, die folgenden dynamische LINQ der Umwandlung in SQL? Ich bin neu in C #. Ich habe einige andere Beiträge, aber ich kann nicht scheinen, um es zu arbeiten.
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;
}
}
}
Lösung
Mit [System.Linq.Dynamic][1]
.
Erhalten Sie die Bedingung von einer Methode und verwenden Sie es in einer einzigen Abfrage.
switch (choice)
{
case case1:
condition = string.Format("{0}.Contains({1})", "Column", "Value"
break;
Andere Tipps
Hey Rony. Ich habe versucht, Ihren Vorschlag und wieder meinen Code (siehe unten) berücksichtigt. Allerdings erhalte ich einen Fehler: Keine Eigenschaft oder ein Feld ‚smith‘ existiert in Typ ‚vCustomer‘ . Durch die Art und Weise, die MessageBox.Show (Bedingung); Zeilenumbrüche Name.Contains (Schmied) , die korrekt aussieht.
Was mache ich falsch? Sorry für ein noob und vielen Dank für Ihre Hilfe sein.
figured it out ... benötigt Suchbegriff mit Anführungszeichen wickeln! Code bearbeitet wurde.
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;
}
}
}