# ER关系字段

## **抽象实体路径**

在实体关系图中，多对多关系用于表示两个实体之间的关系。多对多关系是具有传递性的。例如，如果实体A与实体B具有多对多关系，而实体B与实体C具有多对多关系，则实体A和实体C也具有多对多关系，这是一种间接的多对多关系。

基于多对多关系的传递性，**抽象实体路径**的概念被提出用于描述实体之间这种直接或间接的多对多关系。抽象实体路径将从一个实体到另一个实体的所有实体作为节点来描述任意两个实体之间所具有的多对多关系。例如，实体A和实体B的抽象实体路径为\[A,B]，实体B和实体A的抽象实体路径为\[B,A]，实体C和实体A的抽象实体路径为\[C,B,A]。抽象实体路径包含了任意两个实体之间关系的全部信息，从而用于动态生成复杂的嵌套查询语句。

GoooQo 引入**抽象实体路径**概念，定义名为`entitypath`的标签来表示实体之间的关系。该标签用于查询对象中的用于查询实体关系的字段。例如，实体路径`` `entitypath:"user,role"` ``，基于预定的表名格式，可以得到两个实体表名t\_user和t\_role，中间表表名a\_user\_and\_role，以及两个外键名称user\_id和role\_id，进而生成查询语句：

```sql
SELECT * FROM t_user WHERE
id IN (
    SELECT user_id FROM a_user_and_role WHERE role_id IN (
       SELECT id FROM t_role WHERE ...
    )
)
```

## 示例

表 `t_menu` 有一个列 `parent_id`，它将 `id` 列本身引用为外键。`parent_id` 列用于定义菜单项之间的层次父子关系。菜单通过通用 RBAC 模型作为系统资源分配给用户。那么菜单到用户的实体路径即为：`menu,perm,role,user`，用于生成嵌套查询语句。

```go
import . "github.com/doytowin/goooqo/core"

type MenuEntity struct {
	IntId
	ParentId *int    `json:"parentId,omitempty"`
	Name     *string `json:"name,omitempty"`
}

type MenuQuery struct {
	PageQuery
	Id *int

	// many-to-one:
	// 查询特定父菜单的子菜单：
	// parent_id IN (SELECT id FROM t_menu WHERE [conditions])
	Parent *MenuQuery `entitypath:"menu" localField:"ParentId"`

	// one-to-many:
	// 查询特定子菜单的父菜单：
	// id IN (SELECT parent_id FROM t_menu WHERE [conditions])
	Children *MenuQuery `entitypath:"menu" foreignField:"ParentId"`

	/**
	many-to-many:
	查询特定用户可以访问的菜单：
	id IN (
		SELECT menu_id FROM a_perm_and_menu WHERE perm_id IN (
			SELECT perm_id FROM a_role_and_perm WHERE role_id IN (
				SELECT role_id FROM a_user_and_role WHERE user_id IN (
					SELECT id FROM t_user WHERE [conditions]
				)
			)
		)
	)*/
	User *UserQuery `entitypath:"menu,perm,role,user"`
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://goooqo.docs.doyto.win/zh/query-mapping/query-object/er-query-field.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
