使用 QueryMultiple 时如何确定返回哪些记录?

Posted

技术标签:

【中文标题】使用 QueryMultiple 时如何确定返回哪些记录?【英文标题】:How to determine which records are returned when using QueryMultiple? 【发布时间】:2021-07-15 13:37:04 【问题描述】:

我正在通过执行以下操作来检索记录:

using (var multi = await connection.QueryMultipleAsync(procedureName, param, commandType: CommandType.StoredProcedure))

    var results = new List<dynamic>();

    while (!multi.IsConsumed)
    
        results.Add(multi.Read().ToList());
    

    return results;

到目前为止一切顺利。存储过程通过执行以下操作返回数据:

SELECT * FROM @Orders;
SELECT * FROM @OrderDetails;

是否可以将List&lt;dynamic&gt;更改为Dictionary&lt;string, IEnumerable&lt;dynamic&gt;&gt;并在读取GridReader时自动设置键,这样在上面的示例中,字典将有两个条目,键为Orders和@ 987654328@.

使用Read&lt;T&gt; 不是这个问题的解决方案,因为该方法非常通用并且不知道返回什么。

【问题讨论】:

这能回答你的问题吗? How to return dynamic types List<dynamic> with Dapper ORM 虽然你非常期待 Dapper 猜出使用什么类型,但我不知道。它无法知道正在查询哪个底层表(甚至 如果有 表正在被查询,它可能是 VALUES 或 Json 或 XML),它只能看到列名 为什么要拆分它们? (除非你无法控制)。相反,我会创建一个查询 JOINing OrdersOrderDetails 并为 Dapper 创建一个匹配的数据传输对象类,以将结果映射到您的类。 @EspressoBeans 我无法控制来自存储过程的内容。那两张桌子只是一个例子。表可能彼此无关。 【参考方案1】:

如果您不介意在查询中首先聚合数据,您可以创建一个 JOIN 查询和一个匹配的 Data Transfer Object 类以供 Dapper 映射到。

假设你有这些表:

Orders table:

orders.id
orders.customerid
orders.date
OrderDetails table:

orderdetails.id
orderdetails.orderid
orderdetails.productid
orderdetails.quantity
orderdetails.cost

然后您可以创建一个连接查询来返回相关数据,如下所示:

SELECT 
  orders.id AS OrderId,
  orders.customer AS CustomerId,
  orders.date AS OrderDate,
  orderdetails.productid AS ProductId,
  orderdetails.quantity AS Quantity,
  orderdetails.cost AS Cost
FROM orders
LEFT JOIN orderdetails ON orders.id = orderdetails.orderid

还有一个这样的匹配 DTO:

public class CustomerOrderDto : BaseDto

    public int OrderId  get; set; 
    public int CustomerId  get; set; 
    public DateTime OrderDate  get; set; 
    public int ProductId  get; set; 
    public double Quantity  get; set; 
    public double Cost  get; set; 


CustomerOrder 检索方法:

// get single order and its details
public CustomerOrder GetCustomerOrder(int id)

    string sql = @"SELECT 
                     orders.id AS OrderId,
                     orders.customer AS CustomerId,
                     orders.date AS OrderDate,
                     orderdetails.productid AS ProductId,
                     orderdetails.quantity AS Quantity,
                     orderdetails.cost AS Cost
                   FROM orders
                   LEFT JOIN orderdetails ON orderdetails.orderid = orders.id
                   WHERE orders.id = @Id";

    using (connection...)
    
        return connection.Query<CustomerOrder>(sql, new  Id = id ).SingleOrDefault();
    



// get all orders and their details
public IEnumerable<CustomerOrder> GetCustomerOrders()

    string sql = @"SELECT 
                     orders.id AS OrderId,
                     orders.customer AS CustomerId,
                     orders.date AS OrderDate,
                     orderdetails.productid AS ProductId,
                     orderdetails.quantity AS Quantity,
                     orderdetails.cost AS Cost
                   FROM orders
                   LEFT JOIN orderdetails ON orderdetails.orderid = orders.id";

    using (connection...)
    
        return connection.Query<CustomerOrder>(sql);
    


在我们的应用程序中,我们实际上将有一个静态的SELECT 正文字符串并动态创建 sql WHERE 子句,这样我们就不必重复一堆代码。

【讨论】:

以上是关于使用 QueryMultiple 时如何确定返回哪些记录?的主要内容,如果未能解决你的问题,请参考以下文章

由Dapper QueryMultiple 返回数据的问题得出==》Dapper QueryMultiple并不会帮我们识别多个返回值的顺序

csharp Dapper ODBC QueryMultiple Error

如何根据图像质量确定使用哪种 OCR 方法

从 dapper 中的多个查询返回可枚举的结果

如何确定哪个子窗体有焦点

MFC CControlBar