Gar*_*yle 3 vapor vapor-fluent
我正在努力弄清楚如何使用 Fluent 将两个表连接在一起。本质上我想运行这个 SQL 命令:
SELECT p.name, o.amount, o.amount * p.amount total
FROM "OrderPoints" o
INNER JOIN "Points" p ON o.points_id = p.id
WHERE order_id = 10831
Run Code Online (Sandbox Code Playgroud)
我的两个模型设置如下:
final class OrderPoint: Codable, PostgreSQLModel, Content, Migration {
var id: Int? = nil
var orderID: Order.ID
var pointID: Point.ID
var amount: Double = 0
var point: Parent<OrderPoint, Point> {
return parent(\.pointID)
}
}
final class Point: Codable, PostgreSQLModel, Content, Migration {
var id: Int? = nil
var name: String
var abbrev: String
var amount: Double
}
Run Code Online (Sandbox Code Playgroud)
所以现在在我的控制器中我循环遍历我关心的所有订单:
// SELECT * FROM orders WHERE "month" = '2018-05-01'
let orders = try Order.query(on: req).filter(\Order.month == month).all()
return orders.flatMap(to: View.self) { orders in
let content = try orders.map { (order) -> OrderIndexContent in
let values = try order.orderPoints.query(on: req).all()
Run Code Online (Sandbox Code Playgroud)
order_points我认为这可以获取当前 ID 的所有项目,但我只是不知道如何将其与Points模型连接起来,以便我可以执行其余的查询(即获取相乘的金额和点名称)
Order有多个OrderPoint项目。 OrderPoint有一个项目 Point。Point可以指向许多OrderPoint项目。因此,我认为流利指代事物的方式OrderPoints不是一个枢轴,因为它不是多对多。
下面的方法似乎有效,但这不可能是“正确”的方法,因为这会产生大量额外的 SQL 调用,对吧?
_ = try! order.orderPoints
.query(on: req)
.all()
.map(to: Void.self) { pointsForOrder in
pointsForOrder.forEach { orderPoint in
_ = try! orderPoint.point.get(on: req).map(to: Void.self) {
print("\(order.id!) \(order.name) \($0.abbrev) \(orderPoint.pointID) = \(orderPoint.amount) = \($0.amount * orderPoint.amount)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了从 an 中检索 sPoint中引用的所有 s,您必须查询并加入它。然后你可以添加一个过滤器来过滤你想要查询的订单。OrderPointOrderPointOrderPointOrderPoint
这将导致以下 Fluent 查询:
Point.query(on: req)
.join(field: \OrderPoint.pointID)
.filter(OrderPoint.self, \OrderPoint.orderID == order.id!)
.all()
Run Code Online (Sandbox Code Playgroud)
然而,这个查询只会返回一个 s 数组Point,因此您会错过我们在 Discord 讨论中指出的信息,OrderPoint我们还必须解码OrderPoint,幸运的是 Fluent 有一个很好的方法:.alsoDecode。所以最终的查询将如下所示:
Point.query(on: req)
.join(field: \OrderPoint.pointID)
.filter(OrderPoint.self, \OrderPoint.orderID == order.id!)
.alsoDecode(OrderPoint.self)
.all()
Run Code Online (Sandbox Code Playgroud)
这将返回一个包含Point和 的元组OrderPoint
| 归档时间: |
|
| 查看次数: |
1655 次 |
| 最近记录: |