具有别名的计算列未映射到 TypeORM 实体

Computed column with alias is not mapping into TypeORM Entity

我正在尝试使用 TypeORMMySQL 数据库的 table 中获取数据我的 Express.js 项目。

我正在使用 QueryBuilder 获取数据。

我的实现:

const result = await this.repository.createQueryBuilder("post")
                     .skip((request.PageNo - 1) * request.PageSize)
                     .take(request.PageSize)
                     .select([
                        "post.Id",
                        "post.Title",
                        "SUBSTRING(post.Content, 1, 150) AS post_Content",
                        "post.ReadTime",
                        "post.CreatedDate"
                     ])
                    .getRawAndEntities();

结果:

{
  raw: [
    TextRow {
      post_Id: '457457',
      post_CreatedDate: 2021-03-17T18:00:00.000Z,
      post_Title: 'This is a random title',
      post_ReadTime: 3,
      post_Content: "If you're looking for random paragraphs, you've come to the right place. When a random word or a random sentence isn't quite enough, the next logical "
    }
  ],
  entities: [
    Post {
      CreatedBy: '',
      CreatedDate: 2021-03-17T18:00:00.000Z,
      Content: '',
      Title: 'This is a random title',
      ReadTime: 3,
      IsFeatured: false,
      Id: '457457'
    }
  ]
}

期望: 如您所见,我需要 Content 列的子字符串。我认为我已经将别名添加为 TypeORM 约定。但是该列未映射到 属性.

我也有原始数据,您可以在其中看到带有别名的列的子字符串正在工作。

我试过的备选方案:

但没有一个将 Content 列映射到 Post 实体的 Content 属性。

注意: Content 列仅在我未使用任何别名时映射。

跟踪: 生成的原始 SQL:

  1. 不使用别名时

    SELECT `post`.`Id` 为 `post_Id`, `post`.`CreatedDate` 为 `post_CreatedDate`, `post`.`Title` 为 `post_Title`, `post`.`Content` 为 `post_Content`, `post`.`ReadTime ` 作为 `post_ReadTime` 来自 `帖子` `post` LIMIT 10

  2. 使用别名时

    SELECT `post`.`Id` 为 `post_Id`, `post`.`CreatedDate` 为 `post_CreatedDate`, `post`.`Title` AS `post_Title`, `post`.`ReadTime` AS `post_ReadTime`, SUBSTRING(`post`. `Content`, 1, 150) AS `post_Content` FROM `Posts` `post` 限制 10

请帮忙!!!

编辑(可行的解决方案):

const result = await this.repository.createQueryBuilder("post")
                     .skip((request.PageNo - 1) * request.PageSize)
                     .take(request.PageSize)
                     .select([
                        "post.Id",
                        "post.Title",
                        "post.Content",
                        "SUBSTRING(post.Content, 1, 150) AS post_Content",
                        "post.ReadTime",
                        "post.CreatedDate"
                     ])
                    .getMany();

多年来很多人都问过同样的问题。

示例:

  • Issue 296 Select 个额外的计算列(仍然打开)
  • Issue 1822 添加自定义 select 并映射到 属性 实体(关闭为重复)
  • Issue 7008 无法添加Select 计算结果(仍然打开)
  • PR 4703 添加了对 selecting 计算列的支持(仍然打开)
  • PR 6855 添加 select 和映射功能到 MySQL 驱动程序(仍然打开)

Comment typeorm 作者于 2018-03-26 在第 1822 期发布:“名为 addSelectAndMap 的官方解决方案将在 0.3.0 中进入 QueryBuilder”(没有迹象表明到此为止)。

在问题 #1822 上有一条评论 workaround

首先,您必须将 { select: false } 添加到实体中的计算列

@Column({ select: false } )
Content: string;

然后对计算列使用addSelect(selection, alias)(addSelect with alias overload)

addSelect("SUBSTRING(post.Content,1,3)", "post_Content")