首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用二维数组作为Dapper参数列表

使用二维数组作为Dapper参数列表
EN

Stack Overflow用户
提问于 2020-11-12 00:28:17
回答 1查看 199关注 0票数 1

在Dapper中,可以使用以下代码在where中查询列表:

代码语言:javascript
运行
复制
var sql = "SELECT * FROM Invoice WHERE Kind IN @Kind;";

using (var connection = My.ConnectionFactory())
{
    connection.Open();

    var invoices = connection.Query<Invoice>(sql, new {Kind = new[] {InvoiceKind.StoreInvoice, InvoiceKind.WebInvoice}}).ToList();
}

但是我想查询多个供应商的产品列表和他们的产品代码。为此,我尝试创建一个数组数组。这是我在我的存储库中的方法:

代码语言:javascript
运行
复制
public Dictionary<int, Dictionary<string, Product>> GetGroupedListByRelationIdAndProductCode(Dictionary<int, List<string>> productKeysByRelationId)
{
    Dictionary<int, Dictionary<string, Product>> list = new Dictionary<int, Dictionary<string, Product>>();

    string sql = "SELECT * FROM Products WHERE 1=1 ";

    int i = 0;
    foreach (KeyValuePair<int, List<string>> productKeys in productKeysByRelationId)
    {
        sql = sql + " AND (ManufacturerRelationId = " + productKeys.Key + " AND ManufacturerProductCode in @ProductCodeList[" + i + "] )";
        ++i;
    }

    using (var conn = _connectionFactory.CreateConnection())
    {
        conn.Open();

        var param = new { ProductCodeList = productKeysByRelationId.Select(x => x.Value.ToArray()).ToArray() };

        var productsList = conn.Query<Product>(sql, param).ToList();

        if (productsList.Count > 0)
        {
            foreach (var product in productsList)
            {
                list[product.ManufacturerRelationId][product.ManufacturerProductCode] = product;
            }
        }
    }


    return list;
}

这给了我这个错误:System.ArgumentException: 'No mapping exists from object type System.String[] to a known managed provider native type.'

对如何做到这一点有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-12 16:50:02

您的代码有几个问题。

如果你的productKeysByRelationId中有多个项目,你最终会得到这样的SQL:

代码语言:javascript
运行
复制
WHERE 1=1 AND ManufacturerRelationId = 1 ... AND ManufacturerRelationId = 2

这不太可能返回任何结果,您需要在其中散布一些OR。

你得到的错误是因为你有类似这样的东西:

代码语言:javascript
运行
复制
AND ManufacturerProductCode in @ProductCodeList[0]

Dapper不能处理这个问题。它主要希望查询参数是一个具有几个简单类型或数组的适当命名的成员的对象。

谢天谢地,达珀有一个解决方案,DynamicParameters来拯救!

你可以像这样构造你的查询:

代码语言:javascript
运行
复制
var queryParams = new DynamicParameters();
foreach (var productKeys in productKeysByRelationId)
{
    sql = sql + $" ... AND ManufacturerProductCode in @ProductCodeList{i} )";
    queryParams.Add($"ProductCodeList{i}", productKeys.Value);
    i++;
}

现在您有了正确格式的查询参数,所以您可以这样做:

代码语言:javascript
运行
复制
var productsList = conn.Query<Product>(sql, queryParams).ToList();

这应该可以解决这个问题,但是您真的应该尝试对ManufacturerRelationId进行参数化。这不仅仅是关于SQL注入,可能还有一些与SQL缓存性能相关的事情。您还可以通过使用Dapper.Contrib中的SqlBuilder来使代码更加清晰。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64790314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档