sql - Enkelt tabell-arv med relation som riktar sig mot basklassen i TypeORM
I min app vill jag att användaren ska ha notifikationsobjekt (nyheter) av olika typer. User och NewsItem måste ha en en-till-många-relation, men också, NewsItem är bara en basklass för de olika typerna av faktiska nyhetsobjekt.
Här är min bas NewsItem-klass:
@Entity()
@TableInheritance({ column: { type: "varchar", name: "type"}})
export class NewsItem {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(type => User, user => user.news)
receiver: Promise<User>;
}
Här är User som den är kopplad till:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
// (a lot of irrelevant stuff removed)
@OneToMany(type => NewsItem, newsItem => newsItem.receiver)
news: Promise<NewsItem[]>;
}
Och här är ett exempel på en konkret nyhetsartikel:
@ChildEntity()
export class ConcreteNewsItem extends NewsItem {
@Column()
someData: number;
}
Allt verkar tillräckligt enkelt från dokumentationen. Här är vad jag däremot inte förstår: hur går jag igenom en användares news, kollar vilken exakt typ var och en av dem är, och får ett objekt av en konkret nyhetsposttyp för var och en av dem?
Såvitt jag förstår kommer TypeORM att skapa en kolumn som kallas type i SQL-definitionen av news_item-tabellen - men denna kolumn finns inte tillgänglig på NewsItem-klassen själv, och jag kan inte förstå hur man bygger en fråga som faktiskt skulle ge mig ConcreteNewsItem-objekten!
Svar #1
Gammal fråga, men fortfarande obesvarad. Jag hittade en något elegant lösning på detta. TypeORM frågar faktiskt de konkreta typerna av enheterna. Du kan ta reda på vilken konkret typ resultatentiteten av frågan är genom att jämföra konstruktörens namn med klassnamnet. Precis så här:
const allNews = await repository.find(); //Repository pattern for the query
for (const news in allNews) {
if (news.constructor.name == ConcreteNewsItem.name){
const concreteNews = news as ConcreteNewsItem; //This cast is safe
}
else if(...)
...
}
Hoppas detta hjälper någon.
Redigera :
Ännu bättre, du kan använda instanceof och det fungerar eftersom TypeORM faktiskt använder den konkreta klassens konstruktor.
