【问题标题】:Search on multiple columns - Create where clause在多个列上搜索 - 创建 where 子句
【发布时间】:2018-12-25 06:20:53
【问题描述】:

朋友

如果你有时间解决我的问题,请 我的表单中有很多文本框,只有一个按钮和一个 datagridview 我使用此代码进行搜索

如果我想使用 2 个或更多文本框中的值执行搜索,该怎么办。如果我在名称文本框中输入“r”然后在城市文本框中输入“NY”会怎样。我想看看 gridview 给我的结果。

我试图找到的东西,我什么也没找到

如果我只在一个文本框中搜索,代码就可以工作

热烈的问候

private void Button1_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();

if (txtCIVILIDD.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from Tabl1 where  CIVILIDD = '" + txtCIVILIDD.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
else if (txtName_Arabic.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where Name_Arabic like '%" + txtName_Arabic.Text + "%'", con);
    sda.Fill(dt);
    con.Close();
}
else if (txtusername.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from Tabl1 where  username = '" + txtusername.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
else if (comboBox1.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where status = '" + comboBox1.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
else if (comboBox2.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where confirmation = '" + comboBox2.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
else if (CBgender.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where gender like '%" + CBgender.Text + "%'", con);
    sda.Fill(dt);
    con.Close();
}
else if (CBNATIONALITY.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where NATIONALITY like '" + CBNATIONALITY.Text + "%'", con);
    sda.Fill(dt);
    con.Close();
}
else if (comboBoxGovernorate.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where Governorate = '" + comboBoxGovernorate.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
else if (comboBoxCity.Text.Length > 0)
{
    con.Open();
    SqlDataAdapter sda = new SqlDataAdapter("select * from tabl1 where City = '" + comboBoxCity.Text.Trim() + "'", con);
    sda.Fill(dt);
    con.Close();
}
dataGridView1.DataSource = dt;

我尝试用这段代码解决我的问题,但我发现“SELECT * FROM tabl1 WHERE 1=1”; 它返回 null 给我

private void Button1_Click(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    StringBuilder sqlcommand = "SELECT * FROM tabl1 WHERE 1=1 ";
    if (!string.IsNullOrEmpty(CBgender.Text))
    {
        sqlcommand.Append(" and GENDER LIKE '%");
        sqlcommand.Append(CBgender.Text);
        sqlcommand.Append("%'");
    }
    // repeat for other textbox fields

    dataGridView1.DataSource = dt;
}

my search form

【问题讨论】:

  • 你应该学习如何使用 SQL 参数 - 将数据粘合到字符串中进行查询很长时间以来都不是正确的方法。然后,无需重建数据源,只需使用 DataView 或 RowFilter。
  • @WelcomeOverflow 当我搜索一个文本框时,代码正在与我一起工作

标签: c# winforms datagridview textbox ado.net


【解决方案1】:

这里有两种可能的方法。第一个使用@WelcomeOverflows 的建议,即使用DataTableRowFilter 属性。这样做的好处是您只需执行一个数据库查询,并且过滤是在客户端处理的。但是,不可能轻松地保护RowFilter 免受 SQL 注入的影响(尽管您仍然可以潜在地破坏过滤意图,但您可以对断开连接的数据源造成的损害是有限的)。此外,如果数据集非常庞大,可能不希望一次拉回整个数据集并将其保存在内存中。

// call upon startup to get all the data one time
private void GetData()
{
    DataTable dataSource = new DataTable();
    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["myDatabase"].ConnectionString))
    {
        connection.Open();
        SqlCommand selectCommand = new SqlCommand("SELECT * FROM tabl1", connection);
        SqlDataAdapter adapter = new SqlDataAdapter(selectCommand);
        adapter.Fill(dataSource);
        dataGridView1.DataSource = dataSource;
    }
}

// create a filter for the given field in the database and our control
private string CreateFilter(string fieldName, Control userInputControl, bool exactMatch)
{
    string searchValue = null;
    if (userInputControl is TextBox) searchValue = ((TextBox)userInputControl).Text;
    if (userInputControl is ComboBox) searchValue = ((ComboBox)userInputControl).Text;
    if (String.IsNullOrWhiteSpace(searchValue)) return null;
    if (exactMatch)
        return String.Format("{0}='{1}'", fieldName, searchValue);
    return String.Format("{0} LIKE '%{1}%'", fieldName, searchValue);
}

// set the filter on our data grid view
private void button1_Click(object sender, EventArgs e)
{            
    var filterConditions = new[] {
        CreateFilter("Name_Arabic", txtName_Arabic, false),
        CreateFilter("gender", CBgender, false),
        CreateFilter("CIVILIDD", txtCIVILIDD, true),
        CreateFilter("NATIONALITY", cbNationality, false)
        // etc.
    };

    var dataSource = (DataTable)dataGridView1.DataSource;
    if (!filterConditions.Any(a => a != null))
    {
        dataSource.DefaultView.RowFilter = null;
        return;
    }

    dataSource.DefaultView.RowFilter = filterConditions
        .Where(a => a != null)
        .Aggregate((filter1, filter2) => String.Format("{0} AND {1}", filter1, filter2));
}

第二种方法是直接在数据库查询中过滤,使用SQL参数避免SQL注入。

private string CreateSqlFilter(string fieldName, Control userInputControl, SqlCommand command, bool exactMatch)
{
    string searchValue = null;
    if (userInputControl is TextBox) searchValue = ((TextBox)userInputControl).Text;
    if (userInputControl is ComboBox) searchValue = ((ComboBox)userInputControl).Text;
    if (String.IsNullOrWhiteSpace(searchValue)) return null;

    if (exactMatch)
    {
        command.Parameters.Add(new SqlParameter("@" + fieldName, searchValue));
        return fieldName + " = @" + fieldName;
    }
    else
    {
        command.Parameters.Add(new SqlParameter("@" + fieldName, "%" + searchValue + "%"));
        return fieldName + " LIKE @" + fieldName;
    }
}

private void button2_Click(object sender, EventArgs e)
{
    SqlCommand selectCommand = new SqlCommand();

    var filterConditions = new[] {
        CreateSqlFilter("Name_Arabic", txtName_Arabic, selectCommand, false),
        CreateSqlFilter("gender", CBgender, selectCommand, false),
        CreateSqlFilter("CIVILIDD", txtCIVILIDD, selectCommand, true),
        CreateSqlFilter("NATIONALITY", cbNationality, selectCommand, false)
        // etc.
    };

    string filterCondition = filterConditions.Any(a => a != null) ? filterConditions.Where(a => a != null).Aggregate((filter1, filter2) => String.Format("{0} AND {1}", filter1, filter2)) : (string)null;

    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["myDatabase"].ConnectionString))
    {
        selectCommand.Connection = connection;
        selectCommand.CommandText = filterCondition == null ? "SELECT * FROM tabl1" : "SELECT * FROM tabl1 WHERE " + filterCondition;
        connection.Open();
        SqlDataAdapter adapter = new SqlDataAdapter(selectCommand);
        DataTable dataSource = new DataTable();
        adapter.Fill(dataSource);
        dataGridView1.DataSource = dataSource;
    }
}

【讨论】:

  • @steve16351 如果我想添加更多的 2 过滤器我应该怎么做??
  • 例子已经AND的四个条件并且是可扩展的,什么意思?
  • @steve16351,你的意思是我认为任何文本框都可以工作??
  • 是的,您添加到filterConditions 数组中的任何组合框或文本框都将用于构建过滤器。
【解决方案2】:

创建StringBuilder对象:

StringBuilder sqlcommand = new StringBuilder("SELECT * FROM tabl1 WHERE 1=1");

【讨论】:

  • 当我测试它时(它返回 null )
【解决方案3】:

您可以创建一个参数化查询,该查询将具有空值的参数视为搜索中的中性参数。例如:

SELECT * FROM Product WHERE 
    (Id = @Id OR Id IS NULL) AND
    (Name LIKE '%' + @Name + '%' OR @Name IS NULL) AND
    (Price = @Price OR @Price IS NULL) 

这样,如果您为任何参数传递NULL,则在搜索中不会考虑该参数。

另外,它通过使用参数来防止 SQL 注入。

示例

以下示例假设您有一个名为Product 的表,其中有一个名为Id 的列为INTNameNVARCHAR(100)PriceINT

然后要加载数据,创建以下方法:

public DataTable GetData(int? id, string name, int? price)
{
    DataTable dt = new DataTable();
    var commandText = "SELECT * FROM Products WHERE " +
        "(Id = @Id OR @Id is NULL) AND " +
        "(Name LIKE '%' + @Name + '%' OR @Name IS NULL) AND " +
        "(Price = @Price OR @Price IS NULL)";
    var connectionString = @"Data Source=.;Initial Catalog=SampleDb;Integrated Security=True";
    using (var connection = new SqlConnection(connectionString))
    using (var command = new SqlCommand(commandText, connection))
    {
        command.Parameters.Add("@Id", SqlDbType.Int).Value = 
            (object)id ?? DBNull.Value;
        command.Parameters.Add("@Name", SqlDbType.NVarChar, 100).Value = 
            (object)name ?? DBNull.Value;
        command.Parameters.Add("@Price", SqlDbType.Int).Value = 
            (object)price ?? DBNull.Value;
        using (var datAdapter = new SqlDataAdapter(command))
            datAdapter.Fill(dt);
    }
    return dt;
}

要从TextBox 控件中获取值并传递给GetData,可以使用以下代码:

var id = int.TryParse(idTextBox.Text, out var tempId) ? tempId : default(int?);
var name = string.IsNullOrEmpty(nameTextBox.Text)?null:nameTextBox.Text;
var price = int.TryParse(priceTextBox.Text, out var priceId) ? priceId : default(int?);

然后获取数据:

var data = GetData(id, name, price);

【讨论】:

    猜你喜欢
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多