当前位置: 首页 > 知识库问答 >
问题:

TypeForm:如何实现双向关系,多字段-->一个实体类型

颜高格
2023-03-14

我创建了一个“文档”实体:

例如

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

  @Column()
  name: string;

  @Column()
  path: string;
   ...

}

多个文档可以与不同的实体类型相关:post、userProfile等

例如,在发布实体中,我有几个字段,它们都指定文档关系。

  @OneToOne(type => DocumentEntity)
  @JoinColumn({ name: 'default_document' })
  defaultDocument: DocumentEntity;

  @OneToOne(type => DocumentEntity)
  @JoinColumn({ name: 'featured_document' })
  featuredDocument: DocumentEntity;

  @OneToMany(type => DocumentEntity, document => document.post)
  @JoinColumn({ name: 'other_documents' })
  otherDocs: DocumentEntity[]; 

我不清楚如何使文档关系双向。我曾希望在文档上有一个字段,如:

  @ManyToOne(type => abstractEntity, entity => entity.document)
  parentEntity: abstractEntity;

这样,如果我查询文档实体的父关系,我会得到如下结果:

documents: [
{
id: 1,
name: 'document 1', 
path: 'https://image.hosted.service/1.jpg', 
parentEntityId: 23
}, 
{
id: 2
name: 'document 2', 
path: 'https://image.hosted.service/2.jpg'
parentEntityId: 27
}
] 

但是Typeorm似乎想让我为文件实体上的每个父关系字段定义一个精确的匹配字段,比如:

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

  @Column()
  name: string;

  @Column()
  path: string;
  ...

  @OneToOne(type => PostEntity, post => post.defaultDocument)
  postEntityDefaultDoc: PostEntity;

  @OneToOne(type => PostEntity, post => post.featuredDocument)
  postEntityFeaturedDoc: PostEntity;

  @ManyToOne(type => PostEntity, post => post.otherDocs)
  otherDocs: PostEntity[];


}

为了简单起见,本例中没有M:N关系:文档最多只能有一个父级。

对于父实体字段引用文档的每个可能实例,我必须在文档实体上定义一个新字段,这似乎是不正确的。对文档的查询不会返回一个定义父实体的字段列表,相反,我必须解析/聚合任意数量的字段。

我似乎找不到任何教程/示例,其中一个实体有许多字段,每个字段都引用相同的其他实体,这让我认为我的基本方法是有缺陷的。

共有1个答案

闻人高卓
2023-03-14

秘方是leftJoinAndMapMany,它允许您连接任意实体并将其映射到属性上。

这是我在你的情况下要做的。DocumentEntity的外观如下:

@Entity()
class DocumentEntity {
    @PrimaryGeneratedColumn()
    public id!: number;

    @Column()
    public entity!: string;

    @Column({
        name: 'entity_id',
    })
    public entityId!: string;

    @Column()
    public name!: string;
}

您的PostEntity如下所示:

@Entity()
class PostEntity {
    @PrimaryGeneratedColumn()
    public id!: number;

    @Column()
    public name: string;

    public documents?: DocumentEntity[];
}

正如你可能注意到的,这篇文章上的文件没有署名。这是因为我们将使用上述方法进行连接。您的查询如下所示:

connection
    .getRepository(PostEntity)
    .createQueryBuilder('p')
    .leftJoinAndMapMany(
        'p.documents',
        DocumentEntity,
        'p__d',
        '(p.id = md.entityId AND md.entity = :documentEntity)',
        {
            documentEntity: PostEntity.name,
        },
    )
    .getMany()

这些方法可用于连接这些实体:

  • leftjoin和mapmany
 类似资料:
  • 我有实体FooDetails,它有两个字段:客户和位置列表。Customer有Address(@onetoone单向映射),而Location也有带有@onetoone映射的Address。 碰巧在客户中的地址和在位置中的地址是相同的。所有这些对象都来自远程服务,在保存之前,我手动将远程对象的ID放入实体中。映射如下所示:

  • 问题内容: 我正在尝试使用JPA 2.0创建具有通用关系的多态实体。应该有两个表,一个事件表和一个通知表。在这些表内是彼此相关的具体实体,如下所示: 从逻辑上讲,这应该在hibernate状态下是可能的,因为在SQL中是可能的: 这就是我所拥有的: 使用此代码,我可以持久保存并获取任何Event,Notification,LoginEvent或NotificationEvent,但是当我尝试在JP

  • 我有一个单向关系,其中一个实体有另一个实体的列表(一对多)。 我已将级联类型设置为级联类型。所有的,我得到了错误 在这条线上 我想更新现有的用户条目。如果我将上面的行替换为 它会创建重复条目。有什么解决办法吗。请帮帮我。我的代码:

  • 保存“我的实体”时,通过关系工作的子实体不会保存到它们的表中。我不明白怎么回事。 员工: EmployeePhoneNumber: 如何设置这些字段,然后保存实体: 在完成该方法后,我没有一个错误,所有的工作都是正确的,只是表格没有填满--为什么?

  • 问题内容: 有一个实体类“ A”。A类可能具有相同类型“ A”的子级。如果“ A”是孩子,则也应保留它的父母。 这可能吗?如果是这样,我应该如何在Entity类中映射关系?[“ A”有一个id列。] 问题答案: 是的,这是可能的。这是标准双向@ManyToOne/ @OneToMany关系的特例。之所以特别是因为关系两端的实体都是相同的。JPA 2.0规范的第2.10.2节详细介绍了一般情况。 这

  • 问题内容: 我有一个具有和的实体。我也有一个实体。我试图使单个地址表同时包含送货地址和帐单地址,因为没有什么区别它们,并且在一个或多个订单中帐单地址和送货地址可以相同。我已经在中使用了地址字段,但是我不确定使这种双向传输正确的方法。 我有两个问题: 是否适合地址字段,因为它实际上是n:2关系,我只是使用两个单独的字段来表示?如果没有,我该怎么办? 假设1.可以,那么如何使映射双向化(在实体中应使用