【发布时间】:2022-01-09 23:15:43
【问题描述】:
我有一个部门表,我想在部门下选择多个复选框,然后在数据网格中显示它。当我选择一个选项时,它可以工作,但是如何传递多个值?如queryBuilder图片WHERE userGroup=?所示。
这里我想根据复选框传递多个值:
【问题讨论】:
我有一个部门表,我想在部门下选择多个复选框,然后在数据网格中显示它。当我选择一个选项时,它可以工作,但是如何传递多个值?如queryBuilder图片WHERE userGroup=?所示。
这里我想根据复选框传递多个值:
【问题讨论】:
@values = 'v1,v2,...'
SELECT column_name(s)
FROM table_name
WHERE userGroup IN (SELECT value FROM STRING_SPLIT(@values, ','))
试试 in 子句:https://www.w3schools.com/sql/sql_in.asp
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1, value2, ...);
你的情况
WHERE userGroup in (?,?, ... ,?)
这有点棘手,因为您需要每次通过代码创建 sql 语句,具体取决于用户组中的项目。
不要忘记继续使用参数来保持所有甜蜜的消毒。
在这里查看如何使用代码:Building SQL "where in" statement from list of strings in one line?
【讨论】:
WHERE userGroup in (?,?, ... ,?) 但我需要将字符串作为值传递 SELECT [user].userid, [user].Name, user_group.gName FROM ([user] INNER JOIN user_group ON [user].User_Group = user_group.id) WHERE ([user].User_Group IN (SPLIT('2,3,5,7', ' '))) 这需要一些修复它说在查询生成器中未定义的函数“SPLIT”
一个选项是使用actual parameters 即时构建WHERE IN 条件,而不是传递文本。下面提供的代码适用于 SQL-Server,存储库中也有代码可用于与 OleDb 提供程序一起使用。
注意 使用 C#9、.NET Core 5 编码。如果使用较低的框架,例如4.8 则需要修改DataOperations类中的using声明。
完整代码可在以下 GitHub repository 中找到。
位于类项目中用于创建带参数的 WHERE IN 的基本代码
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
namespace SqlCoreUtilityLibrary.Classes
{
public static class SqlWhereInParamBuilder
{
/// <summary>
/// Creates parameters for IN of the WHERE clause
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="partialClause">SELECT partly built up to WHERE IN ({0})</param>
/// <param name="pPrefix">Prefix for parameter names</param>
/// <param name="parameters">Parameter values</param>
/// <returns></returns>
public static string BuildInClause<T>(string partialClause, string pPrefix, IEnumerable<T> parameters)
{
string[] parameterNames = parameters.Select((paramText, paramNumber)
=> $"@{pPrefix}{paramNumber}").ToArray();
var inClause = string.Join(",", parameterNames);
var whereInClause = string.Format(partialClause.Trim(), inClause);
return whereInClause;
}
/// <summary>
/// Populate parameter values
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cmd">Valid command object</param>
/// <param name="pPrefix">Prefix for parameter names</param>
/// <param name="parameters">Parameter values</param>
public static void AddParamsToCommand<T>(this SqlCommand cmd, string pPrefix, IEnumerable<T> parameters)
{
var parameterValues = parameters.Select((paramText) =>
paramText.ToString()).ToArray();
var parameterNames = parameterValues.
Select((paramText, paramNumber)
=> $"@{pPrefix}{paramNumber}").ToArray();
for (int index = 0; index < parameterNames.Length; index++)
{
cmd.Parameters.Add(new SqlParameter()
{
ParameterName = parameterNames[index],
SqlDbType = SqlTypeHelper.GetDatabaseType(typeof(T)),
Value = parameterValues[index]
});
}
}
}
}
在这种情况下,将所有公司从 SQL-Server 数据库表读取到 CheckedListBox 的表单代码。使用一个按钮,获取每个选中的公司的密钥。
SELECT 语句显示在标签中,结果显示在列表框中。
表格代码
using System;
using System.Linq;
using System.Windows.Forms;
using SimpleExamples.Classes;
using SimpleExamples.Extensions;
namespace SimpleExamples
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Shown += OnShown;
DataOperations.GetCommandText += ReceiveQuery;
}
/// <summary>
/// Show decoded SQL SELECT
/// </summary>
/// <param name="sender"></param>
private void ReceiveQuery(string sender)
{
label1.Text = sender;
}
private void OnShown(object sender, EventArgs e)
{
CompanyCheckedListBox.DataSource = DataOperations.GetCompanies();
}
private void GetSelectedButton_Click(object sender, EventArgs e)
{
CompanyListBox.DataSource = null;
var list = CompanyCheckedListBox.CheckedList();
if (list.Count <= 0) return;
var indices = list.Select(company => company.Id).ToList();
var (companies, exception) = DataOperations.GetByPrimaryKeys(indices);
if (exception is null)
{
CompanyListBox.DataSource = companies;
}
else
{
MessageBox.Show(exception.Message);
}
}
}
}
从 CheckedListBox 中获取选中公司的语言扩展
public static class GenericExtensions
{
public static List<Company> CheckedList(this CheckedListBox source)
=> source.Items.Cast<Company>()
.Where((item, index) => source.GetItemChecked(index)).Select(item => item)
.ToList();
}
公司类
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => Name;
}
【讨论】: