TypeORM 中一对多和多对一关系的问题:生成了错误的 SQL 查询

问题描述 投票:0回答:1

我正在学习 typeORM,但遇到了一个问题。我创建了 3 个实体:CategoryTypeAttributeItemAttributeCategoryType

CategoryTypeAttribute实体:

@Entity('category_type_attribute')
export class CategoryTypeAttribute {
    @PrimaryColumn('uuid', {
        unique: true,
        nullable: false,
        comment: 'Unique identifier for the category type attribute',
    })
    @Generated('uuid')
    id: string;

    @PrimaryColumn({
        name: 'category_type_id',
        comment: 'Id of the associated category type',
        length: 36,
    })
    categoryTypeId: string;

    @ManyToOne(() => CategoryType, (categoryType) => categoryType.categoryTypeAttributes)
    @JoinColumn({ name: 'category_type_id' })
    categoryType: CategoryType;

    @OneToMany(() => ItemAttribute, (itemAttribute) => itemAttribute.categoryTypeAttribute)
    itemAttributes: ItemAttribute[]

    @Column({ type: 'varchar', length: 64, comment: 'Name of the attribute' })
    name: string;

    @Column({
        name: 'data_type',
        type: 'enum',
        enum: ItemDataTypes,
        comment: 'Data type of the attribute',
    })
    dataType: ItemDataTypes;

    @Column({
        name: 'is_required',
        type: 'boolean',
        comment: 'Flag indicating if the attribute is required',
    })
    isRequired: boolean;

    @Column({
        name: 'is_enabled',
        type: 'boolean',
        default: true,
        comment: 'Flag indicating if the attribute is enabled (active)',
    })
    isEnabled: boolean;

    @Column('timestamp', {
        name: 'update_date',
        default: () => 'CURRENT_TIMESTAMP',
        comment: 'Update date of the attribute',
    })
    updateDate: Date;
}

ItemAttribute实体:

@Entity('item_attribute')
export class ItemAttribute {
    @PrimaryColumn('uuid', {
        name: 'item_id',
        length: 36,
        comment: 'Id of the item to which the attribute belongs',
    })
    itemId: string;

    @ManyToOne(() => Item)
    @JoinColumn({ name: 'item_id' })
    item: Item;

    @PrimaryColumn('uuid', {
        name: 'category_type_attribute_id',
        length: 36,
        comment: 'Id of the associated category type attribute',
    })
    categoryTypeAttributeId: string;

    @ManyToOne(() => CategoryTypeAttribute, (categoryTypeAttribute) => categoryTypeAttribute.itemAttributes)
    @JoinColumn({ name: 'category_type_attribute_id' })
    categoryTypeAttribute: CategoryTypeAttribute;

    @ManyToOne(() => User, (user) => user.id)
    @JoinColumn({ name: 'update_user_id' })
    updateUser: User;

    @Column({
        type: 'varchar',
        length: 128,
        nullable: true,
        comment: 'Value of the attribute',
    })
    value: string | null;

    @Column('timestamp', {
        name: 'update_date',
        default: () => 'CURRENT_TIMESTAMP',
        comment: 'Update date of the attribute',
    })
    updateDate: Date;
}

CategoryType 实体:

@Entity('category_type')
export class CategoryType {
    @PrimaryColumn('uuid', {
        unique: true,
        nullable: false,
        comment: 'Unique identifier for the category type',
    })
    @Generated('uuid')
    id: string;

    @Column({
        length: 128,
        nullable: false,
        comment: 'Name for the category type',
    })
    name: string;

    @Column({
        length: 4,
        nullable: false,
        comment: 'Code for the category type',
    })
    code: string;

    @Column('text', {
        nullable: true,
        comment: 'Description for the category type',
    })
    description: string;

    @Column('timestamp', {
        name: 'create_date',
        default: () => 'CURRENT_TIMESTAMP',
        comment: 'The creation date of the category type',
    })
    createDate: Date;

    @OneToMany(() => Category, (category) => category.categoryType)
    category: Category[];

    @OneToMany(
        () => CategoryTypeAttribute,
        (categoryTypeAttribute) => categoryTypeAttribute.categoryType
    )
    categoryTypeAttributes: CategoryTypeAttribute[];
}

问题是我正在尝试连接 CategoryTypeAttribute 和 ItemAttribute 以获得具有类别类型属性

id
、类别类型属性
name
和项目属性
value
的结果。

我已阅读文档和博客示例,并基于此我创建了以下查询生成器:

    const categoryTypeAttributes = await dataSource
        .getRepository(CategoryTypeAttribute)
        .createQueryBuilder('category_type_attribute')
        .select([
            'category_type_attribute.id',
            'category_type_attribute.name',
            'item_attribute.value',
        ])
        .leftJoin(
            'category_type_attribute.itemAttributes',
            'item_attribute'
        )
        .getMany();

得到的结果不是想要的,我检查了ORM生成的sql查询是这样的:

SELECT
    `category_type_attribute`.`id` AS `category_type_attribute_id`,
    `category_type_attribute`.`name` AS `category_type_attribute_name`,
    `category_type_attribute`.`category_type_id` AS `category_type_attribute_category_type_id`,
    `item_attribute`.`value` AS `item_attribute_value`,
    `item_attribute`.`item_id` AS `item_attribute_item_id`,
    `item_attribute`.`category_type_attribute_id` AS `item_attribute_category_type_attribute_id`
FROM
    `category_type_attribute` `category_type_attribute`
    LEFT JOIN `item_attribute` `item_attribute`
    ON `item_attribute`.`category_type_attribute_id` = `category_type_attribute`.`category_type_id`
    AND `item_attribute`.`category_type_attribute_id` = `category_type_attribute`.`category_type_id`;

我很困惑,因为要连接两个表,它使用的是 item_attribute.category_type_attribute_id,这是正确的,而 category_type_attribute.category_type_id,这是不正确的,它应该是

id

所以我正在等待的sql查询如下:

SELECT
    `category_type_attribute`.`id` AS `category_type_attribute_id`,
    `category_type_attribute`.`name` AS `category_type_attribute_name`,
    `category_type_attribute`.`category_type_id` AS `category_type_attribute_category_type_id`,
    `item_attribute`.`value` AS `item_attribute_value`,
    `item_attribute`.`item_id` AS `item_attribute_item_id`,
    `item_attribute`.`category_type_attribute_id` AS `item_attribute_category_type_attribute_id`
FROM
    `category_type_attribute` `category_type_attribute`
    LEFT JOIN `item_attribute` `item_attribute`
    ON `item_attribute`.`category_type_attribute_id` = `category_type_attribute`.`id`;

这个查询就是我需要的。

我不知道我在哪里遇到问题,实体之间的关系是否错误或查询生成器是否错误。我尝试从 item_attribute 实体启动查询,结果是相同的。

typeorm one-to-many many-to-one
1个回答
0
投票

我认为你需要像这样明确指定你的连接条件:

const categoryTypeAttributes = await dataSource
    .getRepository(CategoryTypeAttribute)
    .createQueryBuilder('category_type_attribute')
    .select([
        'category_type_attribute.id',
        'category_type_attribute.name',
        'item_attribute.value',
    ])
    .leftJoin('category_type_attribute.itemAttributes', 'item_attribute', 'item_attribute.categoryTypeAttributeId = category_type_attribute.id')
    .getMany();
© www.soinside.com 2019 - 2024. All rights reserved.