我创建了一个简单的测试项目,以尝试确定@ManyToMany关系为什么返回空值,而不是关系另一侧的对象中的值。我正在使用TypeGraphql,TypeORM和Postgresql。
如果我记录查询结果,则正确的值将显示在日志中。如果将字段设置为可为空,则它们将返回“ null”。如果将其设置为不可为空,则会出现错误-“无法为不可为空的字段Collection.name返回null。”
/Collection.ts
@ObjectType()
@Entity()
export default class Collection extends BaseEntity {
@Field(() => ID, { nullable: true })
@PrimaryGeneratedColumn()
id: number;
@Field()
@Column()
name: string;
@Field(() => [Photo], { nullable: true })
@OneToMany(() => PhotoCollection, (pc) => pc.collection, { nullable: true })
photos: Promise<Photo[]>;
}
/CollectionResolver.ts
@Resolver(() => Collection)
export default class CollectionResolver {
@Query(() => [Collection])
async collections(): Promise<Collection[]> {
const collections = await Collection.find({
relations: ["photos"],
});
console.log(`collections: ${JSON.stringify(collections, null, 2)}`);
return collections;
}
}
/Photo.ts
@ObjectType()
@Entity()
export default class Photo extends BaseEntity {
@Field(() => ID, { nullable: true })
@PrimaryGeneratedColumn()
id: number;
@Field({ nullable: true })
@Column()
title: string;
@Field(() => [Collection])
@OneToMany(() => PhotoCollection, (pc) => pc.photo)
collections: Promise<Collection[]>;
}
/PhotoResolver.ts
@Resolver(() => Photo)
export default class PhotoResolver {
@Query(() => [Photo])
async photos(): Promise<Photo[]> {
const photos = await Photo.find({
relations: ["collections"],
});
console.log(`photos: ${JSON.stringify(photos, null, 2)}`);
return photos;
}
}
/PhotoCollection.ts
@ObjectType()
@Entity()
export default class PhotoCollection extends BaseEntity {
@Field(() => Collection)
@PrimaryColumn()
collectionId: number;
@ManyToOne(() => Collection, (collection) => collection.photos)
@JoinColumn({ name: "collectionId" })
collection: Promise<Collection>;
@Field(() => Photo)
@PrimaryColumn()
photoId: number;
@ManyToOne(() => Photo, (photo) => photo.collections)
@JoinColumn({ name: "photoId" })
photo: Promise<Photo>;
}
[编辑]
这是TypeGraphQL生成的架构。我添加了一个新对象“位置”,它与照片具有一对多关系。
type PhotoCollection {
collectionId: Collection!
photoId: Photo!
}
type Location {
id: ID!
name: String!
photos: [Photo!]!
}
type Photo {
id: ID!
title: String!
location: Location!
collections: [Collection!]!
}
type Collection {
id: ID!
name: String!
photos: [Photo!]!
}
type Query {
collections: [Collection!]!
collection(id: Int!): Collection!
locations: [Location!]!
photos: [Photo!]!
}
查询这种一对多关系很好,并且所有字段都可以通过以下查询解决:
query {
photos {
id
title
location {
id
name
}
}
}
query {
locations {
id
name
photos {
id
title
}
}
}
使用以下查询查询多对多解析为两种方式都为空:
query {
collections {
id
name
photos {
id
title
}
}
}
尽管日志显示以下事实:
collections: [
{
"id": 1,
"name": "first collection",
"photos": [
{
"collectionId": 1,
"photoId": 1,
"photo": {
"id": 1,
"title": "First Photo"
}
}
]
}
]
我意识到一对多和多对多之间的区别在于,除了要包装在一个对象中之外,我要在多对多中解析的数据还包装在一个对象中数组。我将研究如何解决这个问题。
对于任何偶然发现此问题的人,这篇文章非常详尽且有用: