使用inputbox使用dapper过滤asp.net核心剃须刀

时间:2020-09-07 08:01:56

标签: c# sql asp.net-core razor dapper

我有一个已经从数据库中获取数据的查询,现在我想使用剃刀页面中的复选框来过滤数据。 下面是复选框

 <!--check box-->
                    <div id="selection" class="input-group col-md-3 flex-column" style="display: inline-flex;">

                        <div class="form-check">
                            <input type="text" class="form-check-input" value="InterestRate" name="loan" id="intRate">
                            <label class="form-check-label" for="exampleCheck1">Interest Rate</label>
                        </div>
                        <div class="form-check">
                            <input type="text" class="form-check-input" value="LoanAmount" name="loan" id="intRate">
                            <label class="form-check-label" for="exampleCheck1">Interest Rate</label>
                        </div>
                        <div class="form-check">
                            <input type="date" class="form-check-input" value="LoanTrfDate" name="loan" id="transDate">
                            <label class="form-check-label" for="exampleCheck1">Transfer Date</label>
                        </div>
                        <button type="submit" class="btn btn-primary" id="filter">Submit</button>
                    </div>
                    <!--check box-->

我已经通过string[] Requestloans获得了复选框的值,但是问题是如何使用dapper将RequestLoans数组提交给db。 如果两个人有可能,那么我也可以将其应用于两个以上

public async Task<IEnumerable<Loan>> ManageGettingAll(string[] Requestloans, bool includeDeleted, bool showUnapprovedOnly)
{
  IEnumerable<Loan> loans = null;
            
  try
  {
    using (var conn = new SqlConnection(connectionstring))
    {
      await con.OpenAsync();
      string sql = "Select l.*, c.FirstName from dbo.Loan l left join Customer c on  l.CustId=c.CustId";
      if (!includeDeleted)
      {
        sql += " and l.Deleted = 0";
      }
      if (showUnapprovedOnly)
      {
        sql += " and l.Approved = 0";
      }
      loans = await conn.QueryAsync<Loan>(sql);
    }
  }
  catch (Exception)
  {
    throw;
  }
return loans;
}

1 个答案:

答案 0 :(得分:0)

如果在调用之前设法通过将数据绑定到变量或在需要时获取它们的方法,将输入变量存储在Dictionary 内。以下方法可以为您过滤它。

这假定您将键设为列名。而且在这种情况下,它们全都来自同一个表别名(尽管您可以根据需要进行编辑。这只是不断构建准备好的语句来添加动态条件的一种方法)。

public async Task<IEnumerable<Loan>> ManageGettingAll(Dictionary<string, object> Params)
{
  IEnumerable<Loan> loans = null;

  try
  {
    using (var conn = new SqlConnection(connectionstring))
    {
    await conn.OpenAsync();
    string basesql = "Select l.*, c.FirstName from dbo.Loan l left join Customer c on  l.CustId=c.CustId";
    DynamicParameters queryParams = new DynamicParameters();

    if (Params.Count == 0)
    {
      //No params, so no where condition needed.
    }
    else
    {
      bool firstVar = true;                        
      basesql += " WHERE ";
              
      foreach (var paramName in Params.Keys)
      {
        if (!firstVar)
        {
          basesql += " AND ";
        }
        else
        {
          firstVar = false;
        }
        basesql += ("l." + paramName + " = @" + paramName);
        if (Params.TryGetValue(paramName, out object ParamValue))
        {
          queryParams.Add("@" + paramName, ParamValue);
        }
        else
        {
          //Key not found, should be impossible though.
        }
      }                        
    }

    loans = await conn.QueryAsync<Loan>(basesql, queryParams);
    }
  }
  catch (Exception)
  {
    throw;
  }
return loans;
}

如果您建立了这样的字典:

Dictionary<string, object> parameters = new Dictionary<string, object>();

parameters.Add("interestrate", 10);
parameters.Add("transferdate", DateTime.Now);
parameters.Add("loanName", "Mortgage");

ManageGettingAll(parameters);

参数化查询变为:

SELECT l.*, c.FirstName from dbo.Loan l left join Customer c on l.CustId=c.CustId
WHERE l.interestrate = @interestrate AND l.transferdate = @transferdate AND l.loanName = @loanname

执行后,您将提供参数值,Dapper会非常擅长基于您的值进行类型匹配。这也可以解决SQLinjection的一些危险。

还有其他方法可以动态建立查询或插入参数。 将值输入字典后,我会留给您。

Dapper explanation