Quill 找不到案例类属性

问题描述 投票:0回答:1

使用 ZIO 和 Quill 编写简单的 CRUD 应用程序

域模型由用户和角色(一对多)组成

当尝试调用在 quill 上下文中提升的实体之一(或在构建查询的过程中获得)的方法时,我面临编译时异常:

Can't find case class property: typedCode
                roleSchema.filter(r => r.typedCode == lift(roleCode)).take(1)
val dc: db.Ctx.type = db.Ctx
import dc._


def findRoleByCode(roleCode: RoleCode): Result[Option[Role]] =
    dc.run(
        roleSchema.filter(r => r.typedCode == lift(roleCode)).take(1)
    ).map(_.headOption)

架构如下:

用户实体

case class User(
    id: String,
    firstName: String,
    lastName: String,
    age: Int
){
    def typedId: UserId = UserId(id)
}

角色实体

case class Role(
    code: String,
    name: String
){
    def typedCode: RoleCode = RoleCode(code)
}

标识符的用户到角色关联和值类

case class UserToRole(roleId: RoleCode, userId: UserId)

case class RoleCode(code: String) extends AnyVal
case class UserId(id: String) extends AnyVal

我目前得出的结论是,不可能对 Quill 上下文中存在的实体调用方法。我想这是由于宏观评估和某种类型替换

问题是——获得房产不是问题。我可以获得

role.code
作为
String
,但无法调用
.typedCode
。同样适用于用户

编辑

尝试将

.typedCode
.typedId
转换为接受
Unit
作为参数
typedCode(): RoleCode
typedId(): UserId
的方法会导致另一个异常:

Tree 'r.typedCode()' can't be parsed to 'Ast'
                roleSchema.filter(r => r.typedCode() == lift(roleCode)).take(1)

编辑2 在查询中构建值类的实例:

RoleCode(r.code)
结果:

exception during macro expansion: 
scala.reflect.macros.TypecheckException: package module4.homework.dao.entity is not a value
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$3(Typers.scala:44)
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$2(Typers.scala:38)
    at scala.reflect.macros.contexts.Typers.doTypecheck$1(Typers.scala:37)
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$7(Typers.scala:50)
    at scala.reflect.internal.Trees.wrappingIntoTerm(Trees.scala:1891)
    at scala.reflect.internal.Trees.wrappingIntoTerm$(Trees.scala:1888)
    at scala.reflect.internal.SymbolTable.wrappingIntoTerm(SymbolTable.scala:28)
    at scala.reflect.macros.contexts.Typers.typecheck(Typers.scala:50)
    at scala.reflect.macros.contexts.Typers.typecheck$(Typers.scala:32)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:18)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:18)
    at io.getquill.quotation.Parsing$$anonfun$propertyParser$1.applyOrElse(Parsing.scala:540)
    at io.getquill.quotation.Parsing$$anonfun$propertyParser$1.applyOrElse(Parsing.scala:526)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:64)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$Parser.apply(Parsing.scala:35)
    at io.getquill.quotation.Parsing$$anonfun$propertyParser$1.applyOrElse(Parsing.scala:546)
    at io.getquill.quotation.Parsing$$anonfun$propertyParser$1.applyOrElse(Parsing.scala:526)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:64)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$functionApplyParser$1.applyOrElse(Parsing.scala:579)
    at io.getquill.quotation.Parsing$$anonfun$functionApplyParser$1.applyOrElse(Parsing.scala:578)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$operationParser$1.applyOrElse(Parsing.scala:558)
    at io.getquill.quotation.Parsing$$anonfun$operationParser$1.applyOrElse(Parsing.scala:552)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:61)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$Parser.apply(Parsing.scala:35)
    at io.getquill.quotation.Parsing.io$getquill$quotation$Parsing$$equalityWithInnerTypechecksIdiomatic(Parsing.scala:603)
    at io.getquill.quotation.Parsing$$anonfun$equalityOperationParser$1.applyOrElse(Parsing.scala:624)
    at io.getquill.quotation.Parsing$$anonfun$equalityOperationParser$1.applyOrElse(Parsing.scala:622)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$operationParser$1.applyOrElse(Parsing.scala:553)
    at io.getquill.quotation.Parsing$$anonfun$operationParser$1.applyOrElse(Parsing.scala:552)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:61)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$Parser.apply(Parsing.scala:35)
    at io.getquill.quotation.Parsing$$anonfun$queryParser$1.applyOrElse(Parsing.scala:202)
    at io.getquill.quotation.Parsing$$anonfun$queryParser$1.applyOrElse(Parsing.scala:187)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:50)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$Parser.apply(Parsing.scala:35)
    at io.getquill.quotation.Parsing$$anonfun$queryParser$1.applyOrElse(Parsing.scala:230)
    at io.getquill.quotation.Parsing$$anonfun$queryParser$1.applyOrElse(Parsing.scala:187)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:50)
    at io.getquill.quotation.Parsing$$anonfun$astParser$1.applyOrElse(Parsing.scala:48)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
    at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
    at io.getquill.quotation.Parsing$Parser.unapply(Parsing.scala:44)
    at io.getquill.quotation.Parsing$Parser.apply(Parsing.scala:35)
    at io.getquill.quotation.Quotation.$anonfun$quote$1(Quotation.scala:28)
    at io.getquill.util.Interpolator$Traceable.andReturn(Interpolator.scala:145)
    at io.getquill.quotation.Quotation.quote(Quotation.scala:28)
    at io.getquill.quotation.Quotation.quote$(Quotation.scala:24)
    at io.getquill.dsl.QuotationMacro.quote(QuotationDsl.scala:34)
    at jdk.internal.reflect.GeneratedMethodAccessor61.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at scala.reflect.macros.runtime.JavaReflectionRuntimes$JavaReflectionResolvers.$anonfun$resolveJavaReflectionRuntime$5(JavaReflectionRuntimes.scala:45)
    at scala.tools.nsc.typechecker.Macros.macroExpandWithRuntime(Macros.scala:770)

                roleSchema.filter(r => RoleCode(r.code) == lift(roleCode)).take(1)

编辑3 我想设计上就规定我们不能从查询上下文中调用方法。

解决大多数问题的唯一解决方案是更改域模型本身并使用值类作为

User
Role

的案例类参数
scala macros abstract-syntax-tree zio zio-quill
1个回答
0
投票

正如评论中已经回答的那样,Quill 会将字段和案例类翻译为所选的 SQL 方言。没有办法将

RoleCode(code)
转换为 SQL。您应该能够将
typedRole
typedCode
设为案例类的字段,并通过重写此特定案例类的
apply
方法来处理该字段。

© www.soinside.com 2019 - 2024. All rights reserved.