【问题标题】:Param string on Dapper in WHERE clauseWHERE 子句中 Dapper 上的参数字符串
【发布时间】:2021-11-05 20:43:29
【问题描述】:

我的方法的 WHERE 子句中的参数字符串有问题。我正在尝试进行这样的查询:

string query = "SELECT * FROM table WHERE Name @Filter OR Email @Filter";

然后在我的开关里面,他们的情况会是这样的:

public async Task<List<DTO>>Get(FilterDTO filter)
{
    foreach(var f in filter.fields)
    {
        switch(f.Operator)
        {
            case 1:
                if(f.Value == null)
                {
                   f.Value = "IS NULL";
                   queryResult = connection.Query<Model>(query, new {Filter = f.Filter});
                   break;
                }
                else
                    goto case 2;

我的参数字符串有很多问题,因为我看不到调试失败的原因

请注意,我的真实值名称是 FilterValue(此代码是简化的)

我收到此错误:

@Filter 附近的语法不正确

所以我知道我的参数字符串输入有问题,但我看不到它是什么

【问题讨论】:

  • f.Value 是什么,为什么你不使用 in 表达式?我想你错过了什么
  • 我做了一点修改,也许现在更容易理解了。例如,如果我的邮递员输入是 f.Value = null,那么我在 if 条件下输入,f.Value 采用字符串“IS NULL”并进入我的查询但随后失败。
  • 不能“参数化”操作符 - only 值.....所以你不能传入一个包含操作符的表达式参数值

标签: c# dapper


【解决方案1】:

将查询重写为:

SELECT * FROM table WHERE (@Filter is null and Email is null or @Filter = Email) 
                    OR    (@Filter is null and Name is null or @Filter = Name)

在这种情况下,您可以设置参数Filter = null并获得预期的结果。

【讨论】:

    【解决方案2】:

    可能 Dapper 正在使用这个查询:

    SELECT * 
    FROM table 
    WHERE Name = IS NULL OR Email = IS NULL
    

    这是无效的。

    首先创建一个分析器来查看 dapper 实际在数据库上执行的查询(更容易调试这种情况 - 我推荐 MiniProfiler lib)。

    其次,IS NULL 过滤器用于查询字符串或使用:Name = NULL 而不是IS NULL

    【讨论】:

      【解决方案3】:

      我认为你不能像这样使用来自 Dapper 的参数。 要获得有效的查询,您需要拥有

      SELECT * FROM table WHERE Name = @Filter OR Email = @Filter;
      

      但这不适用于 null。

      您实际上需要创建查询,而不仅仅是参数

      const string query = "SELECT * FROM table WHERE Name {0} OR Email {0}";
      var result = conn.Query(string.Format(query, filterValue));
      

      编辑: 如果您可以使用 Dapper.SqlBuilder,您也可以使用 Dapper 构建查询。 像这样的:

      var sqlBuilder = new SqlBuilder();
      string myFilterValue = null;
      if (string.IsNullOrEmpty(myFilterValue))
      {
          sqlBuilder.OrWhere("Name IS NULL").OrWhere("Email IS NULL");
      }
      else
      {
          sqlBuilder.OrWhere("Name = @Filter", new { Filter = myFilterValue }).OrWhere("Email = @Filter", new { Filter = myFilterValue });
      }
      var template = sqlBuilder.AddTemplate("select * from table /**where**/");
      using var conn = new SqlConnection("");
      var result = conn.Query(template.RawSql, template.Parameters);
      

      【讨论】:

        猜你喜欢
        • 2017-04-24
        • 2013-08-24
        • 1970-01-01
        • 2016-11-01
        • 2013-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多