如何让Amplify DataStore查询返回关联子项?
解决Amplify DataStore查询TestResults时加载关联TestResultData并过滤已删除项的问题
一、用DataStore显式加载关联并过滤子项
DataStore默认不会自动加载关联模型,必须通过include参数指定,同时可以给子模型加过滤条件排除软删除的项:
import { DataStore } from '@aws-amplify/datastore'; import { TestResults, TestResultData } from './models'; // 基础查询,加载带过滤的TestResultData关联 const loadTestResults = async () => { const testResults = await DataStore.query(TestResults, undefined, { include: [ { model: TestResultData, // 过滤掉已软删除的子项 predicate: TestResultData.NOT(TestResultData._IS_DELETED(true)) } ] }); return testResults; };
二、结合分页的写法
要保持分页正常,只需在查询参数里加上limit和nextToken即可,和include兼容:
const loadTestResultsWithPagination = async () => { let allResults = []; let nextToken; do { const { items, nextToken: newToken } = await DataStore.query(TestResults, undefined, { include: [ { model: TestResultData, predicate: TestResultData.NOT(TestResultData._IS_DELETED(true)) } ], limit: 10, // 每页10条 nextToken }); allResults = [...allResults, ...items]; nextToken = newToken; } while (nextToken); return allResults; };
三、排查关联不生效的常见原因
- 模型字段大小写匹配:Amplify生成的模型会把Schema中的大写字段转为驼峰式,比如Schema里的
TestResultData在模型中可能是testResultData,确保include里引用的是生成模型的正确名称(检查./models/index.js确认)。 - 重新生成模型:如果修改过Schema,务必运行
amplify codegen models更新模型代码,避免关联映射错误。 - 确认软删除机制:Amplify默认使用软删除,所有删除的项会标记
_isDeleted: true,必须显式过滤,否则会被返回。
四、如果用GraphQL API直接查询的解决方案
若你更倾向于直接调用GraphQL API,可以自定义查询,在服务端过滤已删除项并保留分页:
自定义GraphQL查询
query ListTestResults($limit: Int, $nextToken: String) { listTestResults(limit: $limit, nextToken: $nextToken) { items { id CustomerID lab fasting dateReported # 其他TestResults字段 # 过滤子项中的已删除记录 testResultData(filter: {_isDeleted: {eq: false}}) { items { id name value unit # 其他TestResultData字段 } } } nextToken } }
客户端调用
import { API, graphqlOperation } from '@aws-amplify/api'; const fetchTestResultsViaAPI = async () => { let allResults = []; let nextToken; do { const response = await API.graphql(graphqlOperation(` query ListTestResults($limit: Int, $nextToken: String) { listTestResults(limit: $limit, nextToken: $nextToken) { items { id CustomerID lab testResultData(filter: {_isDeleted: {eq: false}}) { items { id name value } } } nextToken } } `, { limit: 10, nextToken })); const { items, nextToken: newToken } = response.data.listTestResults; allResults = [...allResults, ...items]; nextToken = newToken; } while (nextToken); return allResults; };
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

