Dapper.net的“where ... in”查询在PostgreSQL上不起作用。

18

以下查询总是会产生错误"42601: syntax error at or near "$1" ".

connection.Query<CarStatsProjection>(
                @"select manufacturer, model, year, AVG(price) as averageprice, AVG(miles) as averagemiles, COUNT(*) as count
                        from products
                        where manufacturer IN @manufacturers 
                            AND model IN @models
                            AND year IN @years
                        group by manufacturer, model, year",
                new { manufacturers = new[] { "BMW", "AUDI" }, 
                      models = new[] { "M4", "A3" }, 
                      years = new[] { 2016, 2015 } });

我通过创建下面的方法并内联调用它来解决了这个问题,现在想知道Dapper能否处理带有对象参数的情况?

 public static string ToInSql(this IEnumerable<object> values)
    {
        var flattened = values.Select(x => $"'{x}'");
        var flatString = string.Join(", ", flattened);

        return $"({flatString})";
    }

你确定这是导致错误的代码吗?SQL字符串有两个参数(制造商和型号),但是传递给Dapper的参数有三个(制造商,型号和年份); 但是,Dapper将忽略未使用的参数,因此不是问题。 IN子句和Dapper约定的使用也是正确的。 SQL字符串以字符串插值符号为前缀,但没有发生字符串插值。您的代码中似乎还缺少其他内容; 也许是字符串插值? - Metro Smurf
嗨 - 这是因为我已经开始使用下面的ToInSql()方法,只是撤销了一些操作。如您在更新的帖子中所见,我已经正确地恢复了它。谢谢。 - sjdweb
1个回答

30

PostgreSQL中的IN运算符不支持将数组(或任何其他集合)作为参数,只支持普通列表(使用ToInSql方法生成的列表)。对于PostgreSQL,您需要使用ANY运算符,例如:

SELECT manufacturer, model, year, AVG(price) as averageprice, AVG(miles) as averagemiles, COUNT(*) as count
FROM products
WHERE manufacturer = ANY(@manufacturers)
AND model = ANY(@models)
AND year = ANY(@years)
GROUP BY manufacturer, model, year

2
我收到了一个错误:Npgsql.PostgresException (0x80004005):22P03:无效的数组标志;有什么想法吗? - MuriloKunze
1
我已经点赞了这个回答,因为它给了我非常需要的提示。同时,我在这里也提供了一个“更完整的自上而下”的答案。@MuriloKunze/其他未来的读者,你们可能想要查看这个答案,以获取完整的魔法语法糖:https://dev59.com/DdH7oIgBc1ULPQZFfUm4#75098182 - granadaCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接