【问题标题】:TypeOrm ViewEntity query is incorrectTypeOrm ViewEntity 查询不正确
【发布时间】:2019-11-20 18:59:09
【问题描述】:

我正在关注关于如何创建 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:

选择CountViewEntity.CountOfA AS CountViewEntity_CountOfA, CountViewEntity.CountOfB AS CountViewEntity_CountOfB, CountViewEntity.Total AS CountViewEntity_Total FROM CountViewEntityp> @8

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

我做错了什么?

编辑:

嗯...自从我提出赏金以来已经有一天了,我收到的答案/评论让我思考:我是 MySQL 新手以及 TypeORM 新手,所以也许我只是忽略了 TypeORM 文档的假设制作。我以为生成的 SQL 会查询实际的数据库表,但我只是重读了文档,尤其是这一部分:

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

以前对我来说没有任何意义,但我刚刚遇到了一个叫做 a Database View 的东西。也许我应该先创建一个然后对此进行查询?再次感到乐观...

【问题讨论】:

  • 可能是CountViewEntity,而不是`count_view_entity?
  • 不要以为我明白你的建议:count_view_entity 是由 TypeORM 在进行 SQL 查询时动态生成的;这不是我在任何地方输入的内容。

标签: mysql typeorm


【解决方案1】:

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

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

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

常量.ts:

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

我的实体.ts:

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

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

我的视图实体.ts:

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

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

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

【讨论】:

    【解决方案2】:

    视图实体是一个映射到数据库视图的类。您可以通过定义一个新类来创建视图实体并用@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")
    })
    

    【讨论】:

    • 感谢您的建议;所有 3 个都给了我与我在原始帖子中看到的相同的结果;生成的 SQL 尝试查询名为 count_view_entity 的表,该表不存在。我要运行的实际查询比我发布的要复杂得多;这就是它有子查询的原因,也是我不使用查询生成器的原因
    • 你的回答确实让我思考,我已经发布了对我原来 Q 的更新
    • 我不能相信你的回答,因为它没有解决我的问题,但你让我思考正确的事情,我最终到达了那里。如果您将答案修改为真正解决了我的问题的答案,我将很乐意为您提供赏金。基本上我必须将我的 SQL 移动到数据库视图(我查找了创建视图的代码),然后在 @ViewEntity() 配置中,设置视图名称并将查询更改为 SELECT *
    • @BeetleJuice 你又遇到问题了吗?如果不向我发布错误,它可能应该解决您的问题。
    • 嗨维涅什;不,我解决了我的问题;我写信是为了告诉你我是如何修复它的,这样你就可以调整你的答案来解释修复并获得赏金。基本上你的回答告诉我调整 expression 参数,但问题是我需要首先在 MySQL 服务器上创建一个数据库视图,然后使用表达式查询它:SELECT *
    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2022-01-04
    • 1970-01-01
    • 2020-11-01
    • 2021-01-29
    相关资源
    最近更新 更多