TypeORM查询构建器:如何返回关联的User实体而非AuthToken?
Hey there! The issue you're facing makes total sense—since you're initializing your query builder from the AuthTokenRepository, the getOne() method will always return an instance of AuthToken (even though you've joined the User table). The innerJoinAndSelect here is just loading the User as a related entity onto the AuthToken object, not changing the main return type.
Here are two clean ways to fix this, depending on your use case:
Solution 1: Fetch AuthToken and Extract the Related User (if relations are set up)
First, make sure your AuthToken entity has a defined relation to User (this is the recommended approach for TypeORM):
// auth-token.entity.ts import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm'; import { User } from './user.entity'; @Entity() export class AuthToken { @PrimaryGeneratedColumn() id: number; @Column() token: string; // Define the relation to User (adjust to @OneToOne if each user has one token) @ManyToOne(() => User) user: User; }
Then adjust your query to join using this relation, then pull out the User from the resulting AuthToken:
const authToken = await this.authTokenRepository.createQueryBuilder('authToken') .innerJoinAndSelect('authToken.user', 'user') // Use the relation name from AuthToken .where('authToken.token = :token', { token }) .getOne(); return authToken?.user; // This will be your User entity (or undefined if no match)
Solution 2: Start the Query from UserRepository (cleaner if you only need the User)
If your end goal is just to get the User, it's more intuitive to start your query from the UserRepository. First, ensure your User entity has a relation to AuthToken:
// user.entity.ts import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm'; import { AuthToken } from './auth-token.entity'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; // Your other user columns (name, email, etc.) // Define reverse relation (use @OneToOne if single token per user) @OneToMany(() => AuthToken, authToken => authToken.user) authTokens: AuthToken[]; }
Then build your query from the User side:
return await this.userRepository.createQueryBuilder('user') .innerJoin('user.authTokens', 'authToken') // Join the AuthToken relation .where('authToken.token = :token', { token }) .getOne();
Bonus: If You Don't Want to Use Relations
If you haven't set up entity relations (though I strongly recommend you do), you can specify the join condition manually:
return await this.userRepository.createQueryBuilder('user') .innerJoin('auth_token', 'authToken', 'authToken.user_id = user.id') // Replace with your actual foreign key column .where('authToken.token = :token', { token }) .getOne();
Pick the approach that fits your entity setup best—using relations will keep your code more maintainable in the long run!
内容的提问来源于stack exchange,提问作者micah

