This is my ViewEntity (i am using typeorm) which pulls data from 2 tables: Company and Person.
@ViewEntity({
expression: (dataSource: DataSource) => {
const companySql = dataSource
.createQueryBuilder(Company, 'company')
.select([
'company.id AS "id"',
'company.autoId AS "autoId"',
'company.osId AS "osId"',
'company.annualRevenue AS "annualPremium"',
'company.name AS "name"',
'company.customerNumber AS "customerNumber"',
'company.createdAt AS "createdAt"',
'company.updatedAt AS "updatedAt"',
'customerType.id AS "customerTypeId"',
'lifecycleStage.id AS "lifecycleStageId"',
'customerSegment.id AS "customerSegmentId"',
'createdBy.id AS "createdById"',
'updatedBy.id AS "updatedById"',
])
.leftJoinAndSelect('company.customerType', 'customerType')
.leftJoinAndSelect('company.lifecycleStage', 'lifecycleStage')
.leftJoinAndSelect('company.customerSegment', 'customerSegment')
.leftJoinAndSelect('company.createdBy', 'createdBy')
.leftJoinAndSelect('createdBy.crmUser', 'createdByCrmUser')
.leftJoinAndSelect('company.updatedBy', 'updatedBy')
.leftJoinAndSelect('updatedBy.crmUser', 'updatedByCrmUser')
.leftJoinAndSelect('createdBy.accountType', 'createdByAccountType')
.leftJoinAndSelect('updatedBy.accountType', 'updatedByAccountType')
.getSql();
const personSql = dataSource
.createQueryBuilder(Person, 'person')
.select([
'person.id AS "id"',
'person.autoId AS "autoId"',
'person.osId AS "osId"',
'person.annualIncome AS "annualPremium"',
'person.fullName AS "name"',
'person.customerNumber AS "customerNumber"',
'person.createdAt AS "createdAt"',
'person.updatedAt AS "updatedAt"',
'customerType.id AS "customerTypeId"',
'lifecycleStage.id AS "lifecycleStageId"',
'customerSegment.id AS "customerSegmentId"',
'createdBy.id AS "createdById"',
'updatedBy.id AS "updatedById"',
])
.leftJoinAndSelect('person.customerType', 'customerType')
.leftJoinAndSelect('person.lifecycleStage', 'lifecycleStage')
.leftJoinAndSelect('person.customerSegment', 'customerSegment')
.leftJoinAndSelect('person.createdBy', 'createdBy')
.leftJoinAndSelect('createdBy.crmUser', 'createdByCrmUser')
.leftJoinAndSelect('person.updatedBy', 'updatedBy')
.leftJoinAndSelect('updatedBy.crmUser', 'updatedByCrmUser')
.leftJoinAndSelect('createdBy.accountType', 'createdByAccountType')
.leftJoinAndSelect('updatedBy.accountType', 'updatedByAccountType')
.getSql();
const combinedSql = `(${companySql}) UNION (${personSql})`;
return dataSource
.createQueryBuilder()
.select('*')
.from(`(${combinedSql})`, 'unionQuery');
},
})
export class Customer {
@ViewColumn()
@PrimaryColumn()
id: string;
@ViewColumn()
autoId: string;
@ViewColumn()
name: string;
@ViewColumn()
osId: string;
@ViewColumn()
annualPremium: number;
@ViewColumn()
customerNumber: string;
@ViewColumn()
createdAt: Date;
@ViewColumn()
updatedAt: Date;
@ManyToOne(() => CustomerType)
@JoinColumn({ name: 'customerTypeId' })
customerType: CustomerType;
@ManyToOne(() => LifecycleStage)
@JoinColumn({ name: 'lifecycleStageId' })
lifecycleStage: LifecycleStage;
@ManyToOne(() => CustomerSegment)
@JoinColumn({ name: 'customerSegmentId' })
customerSegment: CustomerSegment;
@ManyToOne(() => Account)
@JoinColumn({ name: 'createdById' })
createdBy: Account;
@ManyToOne(() => Account)
@JoinColumn({ name: 'updatedById' })
updatedBy: Account;
}
As you see, I already have quite a few ManyToOne relations, and I pull them with no big issues. The problem comes when I try to do the same with Address[] (addresses are in many-to-many relation with both companies and people)
This is how I specify many-to-many in for companies and people respectively:
@ManyToMany(() => Address, (address: Address) => address.companies, {
nullable: true,
})
@JoinTable({
name: 'company__companies_address',
joinColumn: { name: 'companyId' },
inverseJoinColumn: { name: 'addressId' },
})
addresses: Address[];
@ManyToMany(() => Address, (address: Address) => address.persons, {
nullable: true,
})
@JoinTable({
name: 'person__persons_addresses',
joinColumn: { name: 'personId' },
inverseJoinColumn: { name: 'addressId' },
})
addresses: Address[];
I have no idea how to left join and select addresses since typeorm documentation is garbage and they don’t mention ManyToMany example anywhere, they only show an example how to fetch ManyToOne relation in ViewEntities. (they do have examples for standard many-to-many relations but not for views, which doesn’t apply in this case)
Has anyone had experience with this?