【问题标题】:Asp.Net How can I pass parameters using an 'IN' clause in the query to refine a searchAsp.Net 如何在查询中使用“IN”子句传递参数以优化搜索
【发布时间】:2015-12-06 18:22:13
【问题描述】:

我正在关注 Mikes 在http://www.mikesdotnetting.com/article/156/webmatrix-database-helpers-for-in-clauses 上的 IN 条款上的帖子,但我无法添加额外的参数。根据他的帖子,我从类别的一些复选框开始并且工作正常,但我为品牌添加了一些其他复选框,但它不起作用。我不确定如何将其他参数传递给 in 子句。

我想要完成的想法是有一个带有不同产品过滤器(类别、品牌、年龄、价格等)的侧栏,当用户点击时,它会更新结果。有人可以帮我解决这个问题吗?

这是我正在使用的代码,但这会产生错误:

// for the categories
var cTemp = Request["categoryId"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var cParms = cTemp.Select((s, i) => "@" + i.ToString()).ToArray();
var cIn = string.Join(",", cParms);

// for the brands
var bTemp = Request["brandId"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var bParms = bTemp.Select((s, i) => "@" + i.ToString()).ToArray();
var bIn = string.Join(",", bParms);

var sql = "SELECT DISTINCT P.ProductID, J.CategoryID, J.BrandID, P.ProductName, P.Price, " +
       "FROM Products P " +
       "JOIN Junction J ON J.ProductID = P.ProductID " +
       "WHERE J.CategoryID IN ({0}) OR J.BrandID IN ({1})";

var products = db.Query(String.Format(sql, cIn, bIn), cTemp, bTemp);

【问题讨论】:

  • 您看到的错误是什么?
  • 这是 cTemp, cParms, cIn 返回的内容: cTemp: System.String[] cTemp:: 1 cParms: System.String[] cParms:: @0 cIn: @0
  • 这是我得到的错误:异常详细信息:System.ArgumentException:不存在从 DbType System.String[] 到已知 SqlCeType 的映射。第 59 行:var products = db.Query(String.Format(sql, cIn, bIn), cTemp, bTemp);
  • @alvin : 尝试从 Query 方法调用中删除 cTemp、bTemp。
  • @Dark Knight 那行给我一个错误:解析查询时出错。 [令牌行号= 1,令牌行偏移量= 247,错误令牌= WHERE]

标签: c# asp.net razor web webmatrix


【解决方案1】:
  1. 检查 String.Format(sql, cIn, bIn) 的值 - 将其设为单独的字符串变量。您将看到此 SQL 表达式中有重复的参数名称:@0、@1 等。

  2. 调用db.Query时,执行:

db.Query(<final sql statement>, allTemp)

其中allTempcInbIn 的串联。

第 2 项是您看到的错误的原因。

【讨论】:

  • 我不明白你的意思,你能告诉我吗
  • 具体有什么不明白的?
  • @alvin:定义sql 变量后,添加var tmp = String.Format(sql, cIn, bIn); 行。在该行(或紧随其后)设置断点并查看tmp 的值。我认为@Igor 的意思是你会发现它包含@0 等定义了两次,所以你可能只会将cTemp 的值加载到两个IN 语句中。 bTemp 可能会被忽略,或者至少会混淆事物。如果我错了,请纠正我...
【解决方案2】:

对于您在评论中提到的错误,请尝试从db.Query 方法中删除参数。您正在将字符串数组传递给sql 参数,这是不正确的。你的方法调用应该是这样的。

var products = db.Query(String.Format(sql, cIn, bIn));

我认为您的WHERE 子句处理也存在错误。试试这样的..

var sql = "SELECT DISTINCT P.ProductID, J.CategoryID, J.BrandID, P.ProductName, P.Price, " +
       "FROM Products P " +
       "JOIN Junction J ON J.ProductID = P.ProductID ";

var whereClause = ""
if(!string.IsNullOrEmpty(cIn)||!string.IsNullOrEmpty(bIn))
{
    whereClause = "WHERE";
    if(!string.IsNullOrEmpty(cIn))
    {
        whereClause+=" J.CategoryID IN ({0}) ";
        if(!string.IsNullOrEmpty(bIn))
        whereClause+=" OR ";
    }
    if(!string.IsNullOrEmpty(bIn))
    {
        whereClause+=" J.BrandID IN ({1}) ";
    }
}
sql = sql+whereClause;

【讨论】:

  • OP 正在使用参数化 sql 语句 - 他必须将参数值传递给 db.Query
  • 起初这也让我很困惑。 String.Format 的结果类似于 @0, @1, @2...。这些是需要传入的预期参数,通过 cTemp 和 bTemp 提供。它们不是价值观本身。
猜你喜欢
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多