【问题标题】:Single table inheritance with relation targeting base class in TypeORMTypeORM 中具有关系目标基类的单表继承
【发布时间】:2019-10-01 12:07:45
【问题描述】:

在我的应用中,我希望用户拥有不同类型的通知项(新闻)。 UserNewsItem 必须是一对多的关系,而且NewsItem 只是不同类型的实际新闻项目的基类。

这是我的基础NewsItem 类:

@Entity()
@TableInheritance({ column: { type: "varchar", name: "type"}})
export class NewsItem {

    @PrimaryGeneratedColumn()
    id: number;

    @ManyToOne(type => User, user => user.news)
    receiver: Promise<User>;

}

这是它所附加的User

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    // (a lot of irrelevant stuff removed)

    @OneToMany(type => NewsItem, newsItem => newsItem.receiver)
    news: Promise<NewsItem[]>;

}

下面是一个具体新闻的例子:

@ChildEntity()
export class ConcreteNewsItem extends NewsItem {

    @Column()
    someData: number;
}

从文档中可以看出这一切都很简单。然而,这是我没有得到的:我如何通过用户的news,检查每个人的确切类型,并为每个人获取具体新闻项目类型的对象?强>

据我了解,TypeORM 将在 news_item 表的 SQL 定义中创建一个名为 type 的列 - 但此列在 NewsItem 类本身上不可用,我不明白如何构建查询这实际上会给我ConcreteNewsItem 对象!

【问题讨论】:

  • 我正在尝试实现这一点 - 你找到解决方案了吗?
  • @maxpaj 不是一个优雅的人,不。对于这种特殊情况,我最终为所有子类型手动构建表,然后当我需要所有类型的消息时迭代所有子类型——这很丑陋,但很有效。对于另一种情况,我构建了一个带有枚举类型字段的基类表,然后为每个子类构建了一个表,其外键为 (id, type) 来自基类表,约束保证该类型将是这个特定的子类型.但是,TypeORM 对 postgresql 枚举的处理非常糟糕,因此维护起来很麻烦。

标签: sql node.js typescript typeorm single-table-inheritance


【解决方案1】:

老问题,但仍然没有答案。我找到了一个有点优雅的解决方案。 TypeORM 实际上查询实体的具体类型。通过将构造函数名称与类名称进行比较,您可以知道查询的结果实体是哪种具体类型。就像这样:

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(...)
   ...
}

希望这对某人有所帮助。

编辑:

更好的是,您可以使用 instanceof 并且它可以工作,因为 TypeORM 实际上使用了具体的类构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多