Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用dapper构建动态参数化查询?_C#_.net_Dapper - Fatal编程技术网

C# 如何使用dapper构建动态参数化查询?

C# 如何使用dapper构建动态参数化查询?,c#,.net,dapper,C#,.net,Dapper,如何使用dapper构建动态参数化查询 我在KeyValuePair中有列及其值 e、 g 我想使用dapper构建动态SQL语句并执行它 string statement = "SELECT * FROM Employee WHERE 1 = 1 "; List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>(); lst.A

如何使用dapper构建动态参数化查询

我在KeyValuePair中有列及其值

e、 g

我想使用dapper构建动态SQL语句并执行它

    string statement = "SELECT * FROM Employee WHERE 1 = 1 ";
    List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
    lst.Add(new KeyValuePair<string,String>("FName","Kim"));
    lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
    lst.Add(new KeyValuePair<string,String>("Gender","Male"));
    foreach(var kvp in lst)
    {
        statement += " AND "+ kvp.Key +" = '"+ kvp.Value +"'";
    }
    using (var connection = _dataAccessHelper.GetOpenConnection())
    {
      try
      {
           //CommandDefinition cmd = new CommandDefinition(statement);

           var searchResult = await connection.QueryAsync<dynamic>(statement);
上述查询失败,因为查询中有特殊字符。 我发现对于参数化语句,可以使用CommandDefinition, 如何使用CommandDefinition执行上述语句而不出错? 或
有没有更好的方法来构建动态sql语句?

不要将查询构建为文本。您可以使用简洁的SqlBuilder,它是这样的:

List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
lst.Add(new KeyValuePair<string,String>("FName","Kim"));
lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
lst.Add(new KeyValuePair<string,String>("Gender","Male"));
var builder = new SqlBuilder();
var select = builder.AddTemplate("select * from Employee /**where**/");
foreach (var kvPair in lst)
{
    builder.Where($"{kvPair.Key} = @{kvPair.Key}", new { kvPair.Value });
}
using (var connection = _dataAccessHelper.GetOpenConnection())
{
    try
    {
        var searchResult = await connection.QueryAsync<dynamic>(select.RawSql, select.Parameters);
    }
    ...

你不应该试图逃避自己的参数,让它整洁。然后,您还将受到SQL注入的保护。

没有理由使用键值对列表来构建具有动态参数的SQL语句。您只需在查询中放置占位符,例如@FName 并将这些占位符的值作为QueryAsync方法的第二个参数提供,方法是传入一个匿名类型,该类型的键与占位符对应,值与要用于查询的动态值对应

string statement = "SELECT * FROM Employee WHERE FName=@FName AND LName=@LName AND Gender=@Gender";
...
var searchResult = await connection.QueryAsync<dynamic>(statement, new { FName = "Kim", LName = "O'reily", Gender="Male" });
可以对泛型字段使用DynamicParameters类

Dictionary<string, object> Filters = new Dictionary<string, object>();
Filters.Add("UserName", "admin");
Filters.Add("Email", "admin@admin.com");
var builder = new SqlBuilder();
var select = builder.AddTemplate("select * from SomeTable /**where**/");
var parameter = new DynamicParameters();
foreach (var filter in Filters)
{
    parameter.Add(filter.Key, filter.Value);
    builder.Where($"{filter.Key} = @{filter.Key}");                        
}


var searchResult = appCon.Query<ApplicationUser>(select.RawSql, parameter);
是Dapper SqlBuilder的替代品,其工作原理如下:

List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
lst.Add(new KeyValuePair<string,String>("FName","Kim"));
lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
lst.Add(new KeyValuePair<string,String>("Gender","Male"));
var builder = new SqlBuilder();
var select = builder.AddTemplate("select * from Employee /**where**/");
foreach (var kvPair in lst)
{
    builder.Where($"{kvPair.Key} = @{kvPair.Key}", new { kvPair.Value });
}
using (var connection = _dataAccessHelper.GetOpenConnection())
{
    try
    {
        var searchResult = await connection.QueryAsync<dynamic>(select.RawSql, select.Parameters);
    }
    ...
列表lst=新列表; lst.添加新的KeyValuePairFName,Kim; 添加新的KeyValuePairLName,O'Reilly; 1.添加新的KeyValuePairGender,男性; 使用var connection=\u dataAccessHelper.GetOpenConnection { var query=connection.QueryBuilder$@SELECT*FROM Employee; lst中的foreachvar kvp 其中${kvp.Key:raw}={kvp.Value}; var searchResult=await query.QueryAsync; } 输出是完全参数化的SQL,其中FName=@p0和LName=@p1等

您只需注意,使用原始修饰符插值的字符串不会作为参数传递,因为您无法将列作为参数传递,因此您应该确保键列名是安全的。本例中的其他字符串值看起来像常规的不安全字符串插值,但它们被转换为参数


免责声明:我是这个库的作者之一

编写一个存储过程并执行它可能更好。您尝试的是典型的SQL注入场景。您注入了参数值,而不是创建参数。事实上,您已经包括了O'Reilly,一个用于测试SQL注入的公共值。如果您想手动构建查询,至少使用AND[+key+]=@+key+,或者更好的方法,$AND[{key}]=@{key}。在QueryAsyncAs中将值作为参数传递我理解,询问者试图在KeyValuePair的列表上进行通用查询。原因是:在某些项目中,mysql中有几十个条件sql FilterInNot可用?@cyrianox我没有测试我只测试了MSSQL和PostgreSQL,但我认为它应该可以工作,因为它只是一个包装器,可以轻松构建简洁的DynamicParameters。你为什么不试试呢?如果它不起作用,请告诉我,您可以在github中打开一个问题。