使用 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<dynamic>
更改为Dictionary<string, IEnumerable<dynamic>>
并在读取GridReader
时自动设置键,这样在上面的示例中,字典将有两个条目,键为Orders
和@ 987654328@.
使用Read<T>
不是这个问题的解决方案,因为该方法非常通用并且不知道返回什么。
【问题讨论】:
这能回答你的问题吗? How to return dynamic types List<dynamic> with Dapper ORM 虽然你非常期待 Dapper 猜出使用什么类型,但我不知道。它无法知道正在查询哪个底层表(甚至 如果有 表正在被查询,它可能是VALUES
或 Json 或 XML),它只能看到列名
为什么要拆分它们? (除非你无法控制)。相反,我会创建一个查询 JOIN
ing Orders
和 OrderDetails
并为 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并不会帮我们识别多个返回值的顺序