[英]TypeORM : relation with where clause defined in entity
我想創建一個 SalesOrder 實體,它與同一實體有 2 個 OneToMany 關系,但標准不同。
最終目標是檢索這樣的地址:
const salesOrder = await SalesOrder.findOne(1, {
relations: ['receiverAddress', 'senderAddress']
});
console.log(salesOrder.receiverAddress)
console.log(salesOrder.senderAddress)
我不知道如何在 SalesOrder 實體中按類型過濾地址關系。
我想做這樣的事情:
// SalesOrder.ts
@Entity()
export class SalesOrder extends BaseEntity {
@Column()
@PrimaryGeneratedColumn()
id: number
@OneToMany(SalesOrderAddress, salesOrderAddress => salesOrderAddress, {
where: {
type: 'receiver' // join condition salesOrderAddress.type = 'receiver'
}
})
receiverAddress: SalesOrderAddress
@OneToMany(SalesOrderAddress, salesOrderAddress => salesOrderAddress, {
where: {
type: 'sender' // join condition salesOrderAddress.type = 'sender'
}
})
senderAddress: SalesOrderAddress
}
問題:在 typeorm 裝飾器中沒有處理where
子句。
是否有可能得到類似的東西(不使用查詢生成器)?
我知道我可以使用 2 個 OneToOne 關系,但這意味着 SalesOrder 數據庫包含兩個外鍵:receiverAddressId 和 senderAddressId。 我更喜歡使用 OneToMany 關系,因為它允許在 SalesOrderAddress 上只有一個外鍵(例如 salesOrderId)。
在您的情況下,我會考慮創建自定義方法來獲取所需的信息。 檢查該示例:
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm';
@Entity({ name: 'Address' })
export class Address extends BaseEntity {
@PrimaryGeneratedColumn({ type: 'int' })
id: number;
@Column({ type: 'varchar', length: 20 })
type: 'receiver' | 'sender';
@Column({ type: 'nvarchar', length: 1024 })
value: string;
// Put the prop that connects this entity to SalesOrder
@ManyToOne(SalesOrder, ref => ref.addresses)
salesOrder: SalesOrder;
}
@Entity({ name: 'SalesOrder' })
export class SalesOrder extends BaseEntity {
@PrimaryGeneratedColumn({ type: 'int' })
id: number;
// Put the prop that connects this entity to Address
@OneToMany(Address, ref => ref.salesOrder)
addresses: Address[];
// Create a generic method to filter
private static getTypeAddresses(id: number, type: 'receiver' | 'sender'): Promise<Address[]> {
if (typeof id !== 'number') {
throw new Error('The entity\'s id must be a number');
}
return Address
.createQueryBuilder('Address')
.select([ 'Address' ])
.innerJoin(
'Address.salesOrder',
'SalesOrder',
'SalesOrder.id = :id',
{ id: id }
)
.where(
'type = :type',
{ type }
)
.getMany();
}
// Later, create your methods to obtain easifully your address
static getReceiverAddresses(id: number): Promise<Address[]> {
return SalesOrder.getTypeAddresses(id, 'receiver');
}
static getSenderAddresses(id: number): Promise<Address[]> {
return SalesOrder.getTypeAddresses(id, 'sender');
}
getReceiverAddresses(): Promise<Address[]> {
return SalesOrder.getTypeAddresses(this.id, 'receiver');
}
getSenderAddresses(): Promise<Address[]> {
return SalesOrder.getTypeAddresses(this.id, 'sender');
}
}
使用示例:
const salesOrder = await SalesOrder.findOne({ id: 1 });
console.log(await salesOrder.getReceiverAddresses());
console.log(await salesOrder.getSenderAddresses());
如果您不想向實體的 class 添加方法,請考慮創建 controller class 或更方便的過程。 例如:
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm';
@Entity({ name: 'Address' })
export class Address extends BaseEntity {
@PrimaryGeneratedColumn({ type: 'int' })
id: number;
@Column({ type: 'varchar', length: 20 })
type: 'receiver' | 'sender';
@Column({ type: 'nvarchar', length: 1024 })
value: string;
// Put the prop that connects this entity to SalesOrder
@ManyToOne(SalesOrder, ref => ref.addresses)
salesOrder: SalesOrder;
}
@Entity({ name: 'SalesOrder' })
export class SalesOrder extends BaseEntity {
@PrimaryGeneratedColumn({ type: 'int' })
id: number;
// Put the prop that connects this entity to Address
@OneToMany(Address, ref => ref.salesOrder)
addresses: Address[];
}
export class SalesOrderCtrl extends SalesOrder {
private static getTypeAddresses(id: number, type: 'receiver' | 'sender'): Promise<Address[]> {
if (typeof id !== 'number') {
throw new Error('The entity\'s id must be a number');
}
return Address
.createQueryBuilder('Address')
.select([ 'Address' ])
.innerJoin(
'Address.salesOrder',
'SalesOrder',
'SalesOrder.id = :id',
{ id: id }
)
.where(
'type = :type',
{ type }
)
.getMany();
}
static getReceiverAddresses(id: number): Promise<Address[]> {
return SalesOrder.getTypeAddresses(id, 'receiver');
}
static getSenderAddresses(id: number): Promise<Address[]> {
return SalesOrder.getTypeAddresses(id, 'sender');
}
getReceiverAddresses(): Promise<Address[]> {
return SalesOrder.getTypeAddresses(this.id, 'receiver');
}
getSenderAddresses(): Promise<Address[]> {
return SalesOrder.getTypeAddresses(this.id, 'sender');
}
}
使用示例:
const salesOrder = await SalesOrderCtrl.findOne({ id: 1 });
console.log(await salesOrder.getReceiverAddresses());
console.log(await salesOrder.getSenderAddresses());
我想創建一個 SalesOrder 實體,它與同一實體有 2 個 OneToMany 關系,但標准不同。
最終目標是檢索這樣的地址:
const salesOrder = await SalesOrder.findOne(1, {
relations: ['receiverAddress', 'senderAddress']
});
console.log(salesOrder.receiverAddress)
console.log(salesOrder.senderAddress)
我不知道如何在 SalesOrder 實體中按類型過濾地址關系。
我想做這樣的事情:
// SalesOrder.ts
@Entity()
export class SalesOrder extends BaseEntity {
@Column()
@PrimaryGeneratedColumn()
id: number
@OneToMany(SalesOrderAddress, salesOrderAddress => salesOrderAddress, {
where: {
type: 'receiver' // join condition salesOrderAddress.type = 'receiver'
}
})
receiverAddress: SalesOrderAddress
@OneToMany(SalesOrderAddress, salesOrderAddress => salesOrderAddress, {
where: {
type: 'sender' // join condition salesOrderAddress.type = 'sender'
}
})
senderAddress: SalesOrderAddress
}
問題:在 typeorm 裝飾器中沒有處理where
子句。
是否有可能得到類似的東西(不使用查詢生成器)?
我知道我可以改用 2 個 OneToOne 關系,但這意味着 SalesOrder 數據庫包含兩個外鍵:receiverAddressId 和 senderAddressId。 我更喜歡使用 OneToMany 關系,因為它允許在 SalesOrderAddress 上只有一個外鍵(例如 salesOrderId)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.