TypeOrm ViewEntity查询不正确

时间:2019-11-20 18:59:09

标签: mysql typeorm

我正在遵循有关如何创建a ViewEntity的TypeOrm文档,以便可以生成和查询数据库的自定义视图。但是,在运行时,生成的SQL不是我期望的。文档提到输入到@ViewEntity()的表达式可以是查询。这是我的模型:

@ViewEntity({
  expression: `
SELECT t1.*, t1.CountOfA + t1.CountOfB AS Total
FROM (
SELECT q.CountOfA, q.CountOfB
FROM questions q
) AS t1`
})
export class CountViewEntity {
  @ViewColumn()
  CountOfA: number;

  @ViewColumn()
  CountOfB: number;

  @ViewColumn()
  Total: number;
}

因此,我希望Repository<CountViewEntity>表中的每一行都为questions提供一条记录,其中包含CountOfA,CountOfB和Total。所以我执行这个:

this.countViewRepository.find();

但是会生成以下SQL:

  

选择CountViewEntityCountOfA AS CountViewEntity_CountOfACountViewEntityCountOfB AS CountViewEntity_CountOfBCountViewEntity。{{1} }从Total CountViewEntity_Totalcount_view_entity

我收到关于表CountViewEntity不存在的错误。

我在做什么错了?

编辑:

嗯...距离我提出赏金已经有一天了,收到的答案/评论让我开始思考:我既是MySQL新手,还是TypeORM新手,所以也许我只是忽略了TypeORM文档的假设使。我以为生成的SQL将查询实际的数据库表,但是我只是重新阅读了文档,尤其是这一部分:

  

视图实体是一个映射到数据库视图的类

对我来说,这什么都没有,但是我刚遇到了a Database View。也许我应该先创建一个,然后对此进行查询?再次感到乐观...

2 个答案:

答案 0 :(得分:0)

视图实体是一个映射到数据库视图的类。您可以通过定义一个新类来创建视图实体,并用@ViewEntity()对其进行标记:

已根据帖子所有者更新

显然,您必须先创建database views,然后再从TypeORM调用它,这会导致错误count_view_entity not existing

@ViewEntity()接受以下选项:

  • name-视图名称。 如果未指定,则视图名称由实体类名称生成。
  • database-所选数据库服务器中的数据库名称。
  • schema-模式名称。
  • expression-视图定义。 必需参数
  

expression可以是带有正确转义的列和表的字符串,   取决于所使用的数据库。

尝试如下

@ViewEntity({
         expression: `
           SELECT t1.*, t1.CountOfA + t1.CountOfB AS Total
           FROM (
                SELECT q.CountOfA, q.CountOfB
                FROM questions q
               ) AS t1`
      })

export class CountViewEntity {

  @ViewColumn()
  CountOfA: number;

  @ViewColumn()
  CountOfB: number;

  @ViewColumn()
  Total: number;
}

您真的需要Sub Query吗,因为在外部选择中选择相同的结果没有意义。

 @ViewEntity({
        expression: `
            SELECT "t1"."CountOfA" AS "CountOfA", "t1"."CountOfB" AS "CountOfB",
                   "t1"."CountOfA" + "t1"."CountOfB" AS "Total"
            FROM "questions" "t1"
               `
            })

此外,您可以使用QueryBuilder

@ViewEntity({ 
    expression: (connection: Connection) => connection.createQueryBuilder()
        .select("t1.CountOfA", "CountOfA")
        .addSelect("t1.CountOfB", "CountOfB")
        .addSelect("t1.CountOfA" + "t1.CountOfB", "Total")
        .from(questions, "t1")
})

答案 1 :(得分:0)

我遇到了同样的问题,发现这是一个配置问题,所以我想分享为我修复的问题。

我在数据库连接上有“ synchronize:false”,因为数据库对象通常在TypeORM之外处理,但是我想在代码内为ViewEntities定义一个表达式。但是,当您禁用数据库连接上的同步时,它不允许您为特定实体覆盖同步。

因此,我更改了数据库连接以允许同步,并使用“ synchronize:false”定义了我在所有实体上使用的常量,然后仅在ViewEntity上使用“ synchronize:true”覆盖了它。

constants.ts:

export const entityDefaults = { 
    database: 'my_db', 
    schema: 'my_schema', 
    synchronize: false
};

my-entity.ts:

import { Entity } from 'typeorm';
import { entityDefaults } from './constants';

@Entity('my_entity', { ...entityDefaults })
export class MyEntity {
...

my-view-entity.ts:

import { ViewEntity } from 'typeorm';
import { entityDefaults } from './constants';

@ViewEntity('my_view_entity', { ...entityDefaults, synchronize: true, expression: 'SELECT ...' })
export class MyViewEntity {
...

然后,当您启动应用程序时,您应该看到一条消息,说明视图已创建。