Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typeorm how to get relations of relations

Tags:

mysql

typeorm

I am getting the Object ChatRoomEntity with entitymanager.findOne method. The ChatRoomEntity has the variable messages which is a OneToMany - ManyToOne Relation. I have no problems to select that but how do I get the user which sent the message. Its a variable on MessageEntity with a OneToMany Relation.

So basically I want to select a room and all messages of it. But all messages should also have their values on fromUser. I select the room like this:

this.entityManager.findOne(ChatRoomEntity, {where: {id: roomToJoin.id}, relations: ['activeUsers', 'messages']}).then(roomEntity => {
// some code
}

Here my entities:

UserEntity


@Entity()
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  registrationDate: Date;

  @ManyToMany(type => ChatRoomEntity, room => room.activeUsers, {cascade: true})
  @JoinTable()
  activeChatRooms: ChatRoomEntity[];

  @OneToMany(type => ChatRoomMessageEntity, msg => msg.fromUser)
  chatRoomMessages: ChatRoomMessageEntity[];
}

ChatRoomEntity

@Entity()
export class ChatRoomEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar', {nullable: true})
  title: string;

  @OneToMany(type => ChatRoomMessageEntity, chatrmsg => chatrmsg.chatRoom)
  messages: ChatRoomMessageEntity[];

  @ManyToMany(type => UserEntity, user => user.activeChatRooms)
  activeUsers: UserEntity[];

}

ChatRoomMessageEntity

@Entity()
export class ChatRoomMessageEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar', {nullable: true})
  message: string;

  @CreateDateColumn()
  creationDate: Date;

  @ManyToOne(type => UserEntity, user => user.chatRoomMessages)
  fromUser: UserEntity;

  @ManyToOne(type => ChatRoomEntity, chatRoom => chatRoom.messages)
  chatRoom: ChatRoomEntity;

}
like image 812
xDrago Avatar asked Nov 25 '19 11:11

xDrago


People also ask

How do you query one to many relationship in TypeORM?

You can omit @JoinColum n in a @ManyToOne / @OneToMany relation. @OneToMany cannot exist without @ManyToOne . If you want to use @OneToMany , @ManyToOne is required. Where you set @ManyToOne - its related entity will have "relation id" and foreign key.

What is relation in TypeORM?

Advertisements. Relations are used to refer the relationship between table in database. In general, a relationship exists between two tables when one of them has a foreign key that references the primary key of the other table.

What is eager relationship?

Eager relations Eager relations are loaded automatically each time you load entities from the database. For example: import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm" import { Question } from "./Question"

What are typeorm entity relations?

In any reasonably realistic data model, there are bound to be relations between tables or entities. ORMs also provide way to developers to describe these entity relations in a programmatic approach. TypeORM Entity Relations is not different.

What is the relationship type in Orm?

TypeORM - Relations. Relations are used to refer the relationship between table in database. In general, a relationship exists between two tables when one of them has a foreign key that references the primary key of the other table. This feature makes relational database more powerful and efficiently store information.

What are the different types of relations in MySQL?

There are several types of relations: cascade: boolean | ("insert" | "update") [] - If set to true, the related object will be inserted and updated in the database. You can also specify an array of cascade options. primary: boolean - Indicates whether this relation's column will be a primary column or not.

How to create a relation with other columns of the related entity?

By default your relation always refers to the primary column of the related entity. If you want to create relation with other columns of the related entity - you can specify them in @JoinColumn as well: Copied! The relation now refers to name of the Category entity, instead of id. Column name for that relation will become categoryName.


3 Answers

We can load sub-relations by using 'relation.subrelation' within the relations array itself like this:

relations: ['relation1', 'relation2', 'relation2.subrelation1']

So for your case, instead of using join you can simply do something like this:

this.entityManager.findOne(ChatRoomEntity, {
        where: {id: roomToJoin.id},
        relations: ['activeUsers', 'messages', 'messages.fromUser'],
      }).then(roomEntity => {
...

This is specified here: https://github.com/typeorm/typeorm/blob/master/docs/find-options.md#basic-options

like image 88
Rachit Magon Avatar answered Oct 17 '22 05:10

Rachit Magon


Using QueryBuilder

await getRepository(UserEntity)
   .createQueryBuilder('user')
   .leftJoinAndSelect('user.profile', 'profile')
   .leftJoinAndSelect('profile.images', 'images')
   .getMany()

Using FindOptions

await getRepository(UserEntity).find({ 
   relations: ['profile', 'profile.images'] 
})
like image 25
Zawad Avatar answered Oct 17 '22 06:10

Zawad


here is the @gradii/fedaco orm how to implement this feature. use can use multi relations by method with

export class User extends Model {
  @HasOneColumn({related: Profile})
  profile;
}
export class Profile extends Model {
  @HasOneColumn({related: Image})
  image;
}
export class Image extends Model {
  name;
}

eager load

User.createQuery().with('profile.image').get()

lazy load

const user = await User.createQuery().first();
const image await (await user.profile).image
like image 1
xsilen T Avatar answered Oct 17 '22 06:10

xsilen T