2017-07-14 35 views
0

我允许用户选择将用于SQL查询Where子句的过滤器。他挑的复选框,例如:如何根据用户选择构建动态字符串?

CreateDate 
User 
Nummer 
Id 

我保持变量为他们每个人:

Dim CreateDate as String = "CreateDate >= 2017-08-01" 
Dim User as String = "John" 
Dim Nummer as String = "789" 
Dim Id as String = "1" 

比方说,用户选择用户,Nummer和ID。这应该构造以下字符串输出:

Dim finalWhereString as String = "CreateDate >= 2017-08-01 And User = John And Id = 1" 

对我来说,棘手的部分是正确连接字符串。如何在字符串之间的正确位置添加“And”子句?

+0

有什么这么棘手的呢? SELECT * From Table_Name WHERE Column1 ='“&variable&”'AND ......我假设你知道你的用户会输入多少个变量。如果不是仅仅使用一堆If ElseIF语句来构建它。 –

+0

取决于用户选择的内容,除了很多其他之外还有其他内容吗? – Dino

+0

不是,您必须检查每个条件,看看是否需要添加到查询中。 –

回答

1

WHERE 1 = 1添加到基本查询,然后将AND添加到每个选定的条件。
肯定使用SqlParameter将值传递给sql查询。

public class Condition 
{ 
    public Func<bool> IsSelected { get; set; } 
    public string Text { get; set; } 
    public SqlParameter Value { get; set; } 
} 

var conditions = new[] 
{ 
    new Condition 
    { 
     IsSelected =() => checkBoxDate.Checked, 
     Text = "CreateDate >= @CreatedDate", 
     Value = new SqlParameter("@CreatedDate", new DateTime(2017, 8, 1)) 
    }, 
    new Condition 
    { 
     IsSelected =() => checkBoxUser.Checked, 
     Text = "User = @User", 
     Value = new SqlParameter("@User", "John") 
    }, 
    new Condition 
    { 
     IsSelected =() => checkBoxNumber.Checked, 
     Text = "Number = @Number", 
     Value = new SqlParameter("@Number", 789) 
    }, 
    new Condition 
    { 
     IsSelected =() => checkBoxId.Checked, 
     Text = "Id = @Id", 
     Value = new SqlParameter("@Id", 12) 
    } 
} 

var selectedConditions = conditions.Where(condition => condition.IsSelected()).ToList(); 


var baseQuery = "SELECT Id, Number, User, CreatedDate FROM MyTable WHERE 1 = 1"; 
var parameters = selectedConditions.Select(condition => condition.Value); 
var commandText = 
    selectedConditions.Aggregate(new StringBuilder(), 
           (text, condition) => 
           { 
            text.Append(" AND "); 
            text.Append(condition.Text); 
            return text; 
           }, 
           (text) => 
           { 
            text.Insert(0, baseQuery); 
            return text.ToString(); 
           }); 

using (var connnection = new SqlConnection(connectionString)) 
using (var command = new SqlCommand(commandText, connection)) 
{ 
    command.Parameters.AddRange(parameters); 
    connection.Open(); 

    // execute command   
} 

由于@jmoreno建议您不要将WHERE 1 = 1添加到查询中。然后SQL建设将看起来像下面的代码 - 选择你认为更适合你的需求的方法。

var baseQuery = "SELECT Id, Number, User, CreatedDate FROM MyTable"; 
var selectedText = selectedConditions.Select(condition => condition.Text); 
var commandText = 
    selectedConditions.Any() 
     ? $"{baseQuery} WHERE {string.Join(" AND ", selectedText)}" 
     : baseQuery; 
+0

使用任何和string.join将允许忽略WHERE 1 = 1。 – jmoreno

+0

@jmoreno,正确的,这是我首先想到的,但是'Where 1 = 1'代码变得更加直截了当。 – Fabio

+0

我不明白。 'string whereClause =!selectedConditions.Any? “”:“WHERE”+ string.Join(“AND”,selectedConditions.Select(c => c.Text)); commandText = baseQuery + whereClause;'。 – jmoreno

相关问题