TypeORM:什么时候可以省略连接条件?
TypeORM: when can join condition be omitted?
我正在使用 TypeORM 进行两个项目。在其中一个项目中,当我使用查询生成器 select 数据并且查询包含连接时,生成的查询不包含连接条件,生成以下查询:
SELECT *
FROM `alarms`.`faultLog` `fl`
INNER JOIN `alarms`.`alarm` `a`
它给出了 2 543 922 个结果,而不是预期的 1743 个结果。
使用的查询:
return this.faultsRepository
.createQueryBuilder('fl')
.innerJoin('fl.alarm', 'a')
.getRawMany();
如果我将条件添加为 innerjoin
函数的第三个参数,则以下查询无效:
SELECT *
FROM `alarms`.`faultLog` `fl`
INNER JOIN `alarms`.`alarm` `a`
ON AND (`a`.`id` = fl.alarmId)
如果我将查询中 属性 的名称从 fl.alarm
更改为 alarm
,那么生成的查询就可以了。
在另一个项目中,我有一个类似的查询,没有造成问题,其中生成的查询包含连接条件:
return this._recipeRepository
.createQueryBuilder('r')
.innerJoin('r.type', 'rType')
.innerJoin('r.equipment', 'eq')
.innerJoin('r.versions', 'rVers')
.select([
'r.id as id',
'r.name as name',
'rType.name as type',
'r.SKU as sku',
'r.description as description',
'rVers.id as versionId',
'rVers.versionNumber as version'
])
.getRawMany();
我检查了 TypeORM 初始化和存储库配置,一切似乎都是等效的,所以我不明白这里发生了什么。
精简实体:
@Entity({
name: "alarm",
database: 'alarms',
synchronize: false,
})
export class AlarmEntity {
@PrimaryGeneratedColumn({
name: 'id',
type: 'integer'
})
@Generated('increment')
id: number;
@Column({
name: 'description',
type: 'varchar',
length: '200'
})
description: string;
@OneToMany(
() => FaultLogEntity,
faultLog => faultLog.alarm,
{
cascade: true
}
)
faultLogs: FaultLogEntity[];
}
@Entity({
name: "faultLog",
database: 'alarms',
synchronize: false
})
export class FaultLogEntity {
@PrimaryGeneratedColumn({
name: 'id',
type: 'integer'
})
id: number;
@Column({type: 'datetime'})
timestampAppearance:Date;
@OneToMany(() => AlarmEntity, alarm => alarm.faultLogs)
@JoinColumn({ name: 'alarmId' })
alarm: AlarmEntity;
}
存储库配置:
export const alarmsProviders = [
{
provide: "AlarmEntity",
useFactory: (connection: Connection) => connection.getRepository(AlarmEntity),
inject: [Constants.DATABASE_CONNECTION]
},
{
provide: "FaultLogEntity",
useFactory: (connection: Connection) => connection.getRepository(FaultLogEntity),
inject: [Constants.DATABASE_CONNECTION]
},
]
数据库连接:
export const databaseProviders = [
{
provide: Constants.DATABASE_CONNECTION,
useFactory: async () => await createConnection({
type: 'mysql',
host: 'localhost',
port: 3000,
username: 'xxx',
password: 'xxx',
database: 'alarms',
synchronize: false,
logging: true,
entities: [
__dirname + '/../**/*.entity{.ts,.js}',
],
}),
},
];
应用模块中的用法:
@Module({
controllers: [AppController, AlarmsController],
providers: [AppService, AlarmsService, ...databaseProviders, ...alarmsProviders]
})
export class AppModule {
}
所以,主要问题是:TypeORM 需要什么来自动推断连接条件?我在这里错过了什么?
其中一个实体应具有 ManyToOne 关系,您应尝试将 FaultLogEntity 中的关系更改为 ManyToOne
我正在使用 TypeORM 进行两个项目。在其中一个项目中,当我使用查询生成器 select 数据并且查询包含连接时,生成的查询不包含连接条件,生成以下查询:
SELECT *
FROM `alarms`.`faultLog` `fl`
INNER JOIN `alarms`.`alarm` `a`
它给出了 2 543 922 个结果,而不是预期的 1743 个结果。
使用的查询:
return this.faultsRepository
.createQueryBuilder('fl')
.innerJoin('fl.alarm', 'a')
.getRawMany();
如果我将条件添加为 innerjoin
函数的第三个参数,则以下查询无效:
SELECT *
FROM `alarms`.`faultLog` `fl`
INNER JOIN `alarms`.`alarm` `a`
ON AND (`a`.`id` = fl.alarmId)
如果我将查询中 属性 的名称从 fl.alarm
更改为 alarm
,那么生成的查询就可以了。
在另一个项目中,我有一个类似的查询,没有造成问题,其中生成的查询包含连接条件:
return this._recipeRepository
.createQueryBuilder('r')
.innerJoin('r.type', 'rType')
.innerJoin('r.equipment', 'eq')
.innerJoin('r.versions', 'rVers')
.select([
'r.id as id',
'r.name as name',
'rType.name as type',
'r.SKU as sku',
'r.description as description',
'rVers.id as versionId',
'rVers.versionNumber as version'
])
.getRawMany();
我检查了 TypeORM 初始化和存储库配置,一切似乎都是等效的,所以我不明白这里发生了什么。
精简实体:
@Entity({
name: "alarm",
database: 'alarms',
synchronize: false,
})
export class AlarmEntity {
@PrimaryGeneratedColumn({
name: 'id',
type: 'integer'
})
@Generated('increment')
id: number;
@Column({
name: 'description',
type: 'varchar',
length: '200'
})
description: string;
@OneToMany(
() => FaultLogEntity,
faultLog => faultLog.alarm,
{
cascade: true
}
)
faultLogs: FaultLogEntity[];
}
@Entity({
name: "faultLog",
database: 'alarms',
synchronize: false
})
export class FaultLogEntity {
@PrimaryGeneratedColumn({
name: 'id',
type: 'integer'
})
id: number;
@Column({type: 'datetime'})
timestampAppearance:Date;
@OneToMany(() => AlarmEntity, alarm => alarm.faultLogs)
@JoinColumn({ name: 'alarmId' })
alarm: AlarmEntity;
}
存储库配置:
export const alarmsProviders = [
{
provide: "AlarmEntity",
useFactory: (connection: Connection) => connection.getRepository(AlarmEntity),
inject: [Constants.DATABASE_CONNECTION]
},
{
provide: "FaultLogEntity",
useFactory: (connection: Connection) => connection.getRepository(FaultLogEntity),
inject: [Constants.DATABASE_CONNECTION]
},
]
数据库连接:
export const databaseProviders = [
{
provide: Constants.DATABASE_CONNECTION,
useFactory: async () => await createConnection({
type: 'mysql',
host: 'localhost',
port: 3000,
username: 'xxx',
password: 'xxx',
database: 'alarms',
synchronize: false,
logging: true,
entities: [
__dirname + '/../**/*.entity{.ts,.js}',
],
}),
},
];
应用模块中的用法:
@Module({
controllers: [AppController, AlarmsController],
providers: [AppService, AlarmsService, ...databaseProviders, ...alarmsProviders]
})
export class AppModule {
}
所以,主要问题是:TypeORM 需要什么来自动推断连接条件?我在这里错过了什么?
其中一个实体应具有 ManyToOne 关系,您应尝试将 FaultLogEntity 中的关系更改为 ManyToOne