我想原來的問題是想知道如何從用戶的輸入中動態生成它,然後使用適當的sql參數來執行查詢。
的SQL參數的用法,通常我做的是使用一個通用的helper方法,一個簡單的例子(未測試):
public static class SqlHelpers
{
public static IEnumerable<T> ExecuteAdhocQuery<T>(SqlConnection con, string sql, CommandType cmdType, Func<SqlDataReader, T> converter, params SqlParameter[] args)
{
try
{
using (SqlCommand cmd = new SqlCommand(sql, con) { CommandType = cmdType })
{
cmd.Parameters.AddRange(args);
if (con.State != ConnectionState.Open) { con.Open(); }
var ret = new List<T>();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
ret.Add(converter.Invoke(rdr));
}
}
return ret;
}
}
catch (Exception e)
{
// log error?
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw e; // handle exception...
}
}
public void Test()
{
using (SqlConnection con = new SqlConnection("connection string here"))
{
var data = ExecuteAdhocQuery(con,
"SELECT ID, Name FROM tblMyTable WHERE ID = @Id and Status = @Status;",
CommandType.Text, (x) => new { Id = x.GetInt32(0), Name = x.GetString(1) },
new SqlParameter("@Id", SqlDbType.Int) { Value = 1 },
new SqlParameter("@Status", SqlDbType.Bit) { Value = true });
Console.WriteLine(data.Count());
}
}
}
當然
,這只是閱讀,用於插入/更新,也可以創建類似的方法。
但是複雜的部分是如何使它具有未知數量的條件以及它們之間的關係。所以一個快速的建議是使用委託方法或類來完成這項工作。樣本(未測試):
public static Dictionary<string, SqlParameter> GetParamsFromInputString(string inputString)
{
var output = new Dictionary<string, SqlParameter>();
// use Regex to translate the input string (something like "[CookingTime] < 30 and [Cost] < 20") into a key value pair
// and then build sql parameter and return out
// The key will be the database field while the corresponding value is the sql param with value
return output;
}
public void TestWithInput(string condition)
{
var parameters = GetParamsFromInputString(condition);
// first build up the sql query:
var sql = "SELECT Id, Name from tblMyTable WHERE " + parameters.Select(m => string.Format("{0}={1}", m.Key, m.Value.ParameterName)).Aggregate((m,n) => m + " AND " + n);
using (SqlConnection con = new SqlConnection("connection string here"))
{
var data = ExecuteAdhocQuery(con,
sql,
CommandType.Text,
(x) => new { Id = x.GetInt32(0), Name = x.GetString(1) },
parameters.Select(m => m.Value).ToArray());
}
}
對於靜態函數GetParamsFromInputString,它只是一個示例。實際上它可能會非常複雜,這取決於您的需求。例如,您可能希望包含運算符(不管它是否>,<或<>,...)。
並且您可能還希望包括條件之間的連詞,無論是AND還是OR。
構建委託類來完成這個工作,如果它非常複雜的話。
您可以創建一個動態查詢 – Dhaval
動態查詢是不是在這裏一個很好的解決方案,您使用的用戶輸入來創建查詢,這是非常糟糕的主意,並開放給SQL注入 –
@rs根本不符合事實,您可以創建一個參數化的動態查詢字符串。 – Phill