Skip to main content

计算字段

计算字段允许你根据现有数据派生新字段。一个常见的例子是当你想要计算全名时。在数据库中,你可能只存储名字和姓氏,但你可以定义一个函数,通过组合名字和姓氏来计算全名。计算字段是只读的,存储在应用的内存中,而不是数据库中。

¥Computed fields allow you to derive a new field based on existing data. A common example is when you want to compute a full name. In your database, you may only store the first and last name, but you can define a function that computes a full name by combining the first and last name. Computed fields are read-only and stored in your application's memory, not in your database.

使用 Prisma 客户端扩展

¥Using a Prisma Client extension

以下示例说明如何创建 Prisma 客户端扩展,该 Prisma 客户端扩展 在运行时将 fullName 计算字段添加到 Prisma 架构中的 User 模型。

¥The following example illustrates how to create a Prisma Client extension that adds a fullName computed field at runtime to the User model in a Prisma schema.

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient().$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(user) {
return `${user.firstName} ${user.lastName}`
},
},
},
},
})

async function main() {
/**

* Example query containing the `fullName` computed field in the response
*/
const user = await prisma.user.findFirst()
}

main()
Show CLI results

计算字段是类型安全的,可以返回从串联值到复杂对象或函数的任何内容,这些对象或函数可以充当模型的实例方法。

¥The computed fields are type-safe and can return anything from a concatenated value to complex objects or functions that can act as an instance method for your models.

Instructions prior to Prisma ORM 4.16.0
警告

对于从 Prisma ORM 版本 4.16.0 开始普遍可用的 Prisma 客户端扩展,不建议执行以下步骤。请使用 客户端扩展 来实现这一点。

¥With Prisma Client extensions Generally Available as of Prisma ORM version 4.16.0, the following steps are not recommended. Please use a client extension to accomplish this.

Prisma Client 本身尚不支持计算字段,但是,你可以定义一个接受泛型类型作为输入的函数,然后扩展该泛型以确保其符合特定结构。最后,你可以返回带有附加计算字段的泛型。让我们看看它会是什么样子:

¥Prisma Client does not yet natively support computed fields, but, you can define a function that accepts a generic type as an input then extend that generic to ensure it conforms to a specific structure. Finally, you can return that generic with additional computed fields. Let's see how that might look:

// Define a type that needs a first and last name
type FirstLastName = {
firstName: string
lastName: string
}

// Extend the T generic with the fullName attribute
type WithFullName<T> = T & {
fullName: string
}

// Take objects that satisfy FirstLastName and computes a full name
function computeFullName<User extends FirstLastName>(
user: User
): WithFullName<User> {
return {
...user,
fullName: user.firstName + ' ' + user.lastName,
}
}

async function main() {
const user = await prisma.user.findUnique({ where: 1 })
const userWithFullName = computeFullName(user)
}

在上面的 TypeScript 示例中,定义了 User 泛型来扩展 FirstLastName 类型。这意味着你传递到 computeFullName 的任何内容都必须包含 firstNamelastName 键。

¥In the TypeScript example above, a User generic has been defined that extends the FirstLastName type. This means that whatever you pass into computeFullName must contain firstName and lastName keys.

还定义了 WithFullName<User> 返回类型,它采用 User 的任何内容并添加 fullName 字符串属性。

¥A WithFullName<User> return type has also been defined, which takes whatever User is and tacks on a fullName string attribute.

通过此函数,任何包含 firstNamelastName 键的对象都可以计算 fullName。很整洁,对吧?

¥With this function, any object that contains firstName and lastName keys can compute a fullName. Pretty neat, right?

更进一步

¥Going further

  • 了解如何使用 Prisma 客户端扩展 将计算字段添加到你的架构中 — example

    ¥Learn how you can use Prisma Client extensions to add a computed field to your schema — example.

  • 了解如何将 computeFullName 功能移至 定制模型

    ¥Learn how you can move the computeFullName function into a custom model.

  • 有一个 打开功能请求 可以为 Prisma 客户端添加原生支持。如果你希望看到这种情况发生,请务必对该问题进行投票并分享你的用例!

    ¥There's an open feature request to add native support to Prisma Client. If you'd like to see that happen, make sure to upvote that issue and share your use case!