2.8 KiB
2.8 KiB
Ent Edges 使用说明(game 模块)
本文说明 app/game/rpc/internal/models/schema 下 Edges 的定义方式、生成方式,以及在业务代码中如何使用。
1. 当前 game 模块关系设计
基于 desc/sql/game 的表结构,当前主要关系:
players1:Nplayer_servicesplayer_services.player_id -> players.id
shops1:Nshop_playersshop_players.shop_id -> shops.id
players1:Nshop_players(逻辑关联)shop_players.player_id -> players.id
shops1:Nshop_invitationsshop_invitations.shop_id -> shops.id
players1:Nshop_invitations(收到邀请)shop_invitations.player_id -> players.id
players1:Nshop_invitations(发起邀请)shop_invitations.invited_by -> players.id
2. Edge 定义规则
2.1 在子表(持有外键字段)上定义 edge.From(...).Field(...)
示例(player_services):
edge.From("player", Players.Type).Ref("services").Field("player_id").Required().Unique()
含义:
- 当前实体(
player_services)通过player_id指向一个players Unique()表示每条player_services记录只对应一个 player(典型 N:1 子侧定义)
2.2 在父表定义反向 edge.To(...)
示例(players):
edge.To("services", PlayerServices.Type)
含义:
- 一个 player 可以有多条 service(1:N)
3. 代码生成
在项目根目录执行:
go run entgo.io/ent/cmd/ent generate ./app/game/rpc/internal/models/schema
如果你后续为 schema 增加了注解或字段,重复执行同一命令即可刷新生成代码。
4. 业务查询示例
以下为典型写法,具体包路径以你项目实际生成结果为准。
4.1 查询某个玩家及其所有服务
player, err := client.Players.
Query().
Where(players.ID(playerID)).
WithServices().
Only(ctx)
4.2 查询某个店铺及其成员关系记录
shop, err := client.Shops.
Query().
Where(shops.ID(shopID)).
WithMemberships().
Only(ctx)
4.3 查询某玩家收到的邀请
invitations, err := client.Players.
QueryReceivedInvitations(player).
All(ctx)
5. 常见坑
edge.From(...).Field(...)的字段名必须是当前 schema 里真实存在的字段。Ref("...")名称要和对端edge.To("...")保持一致。- 同一实体指向同一目标实体的多条边(例如邀请的
player和inviter)必须使用不同 edge 名称,避免代码生成冲突。 - 如果 SQL 没有声明外键但你定义了带
Field(...)的 edge,迁移时可能会生成外键约束;若不想生成,请保持和 SQL 一致或在迁移层显式控制。
6. 当前文件位置
- Schema 目录:
app/game/rpc/internal/models/schema - SQL 来源:
desc/sql/game