【问题标题】:Dynamic Linq To Sql With ComboBox and Column.Contains带有 ComboBox 和 Column.Contains 的动态 Linq To Sql
【发布时间】:2010-11-05 22:04:12
【问题描述】:

我在表单上有一个文本框、组合框、按钮和 DataGridView,用于从 MSSQL 视图 (vCustomer) 搜索和返回客户信息。它工作得很好,但我知道我的代码可以更有效率。组合框中的四个项目代表要搜索的列。

有没有一种简单的方法可以将以下内容转换为动态 LINQ to SQL?我是 C# 新手。我查看了其他一些帖子,但似乎无法正常工作。

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; 
        }
    }
}

【问题讨论】:

    标签: c# database linq linq-to-sql dynamic-sql


    【解决方案1】:

    使用[System.Linq.Dynamic][1]

    从方法中获取条件并在单个查询中使用它。

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

    【讨论】:

    • 我在 CSharpSamples 文件中找到了一个名为 Dynamic.cs 的文件。该文件具有正确的名称空间 - 这是您的意思吗?我会试试看。
    【解决方案2】:

    嘿,罗尼。我尝试了您的建议并重构了我的代码(见下文)。但是,我收到一个错误:No property or field 'smith' exists in type 'vCustomer'。顺便说一句,MessageBox.Show(condition);行返回看起来正确的 Name.Contains(smith)

    我做错了什么?很抱歉成为菜鸟,感谢您的帮助。

    想通了...需要用双引号包裹搜索字符串!代码已编辑。

    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; 
            }
        }
    }
    

    【讨论】:

    • 哦,伙计...如果我在搜索字段中输入“smith”,它就可以工作。所以,我想我只是在我的搜索字符串周围添加双引号,它适用于所有人!我试过“o'rei”,它奏效了!我会更新我的代码。我将 ,txtSearch.Text) 更改为 ,"\"" + txtSearch.Text + "\"") 并且有效!
    • 注意,如果列是整数类型,这不起作用。如果列是 Int 类型,则必须删除双引号。有没有办法先检查列数据类型是什么?
    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多