joinLeft error: constructor cannot be instantiated to expected type
joinLeft error: constructor cannot be instantiated to expected type
我正在将一些代码从 Slick 2.1 转换到 3.0.3,当我将我的连接从使用 leftJoin
迁移到 joinLeft
时,我收到了这个错误,我不确定如何解决:
[error] ContentRepoLocal.scala:84: constructor cannot be instantiated to expected type;
[error] found : (T1, T2)
[error] required: slick.lifted.Rep[Option[(repo.model.UserContentTable, repo.model.ContentTable)]]
[error] .map { case (u, (uc, c)) => (u, c.optionProjection) }
[error] ^
[error] ContentRepoLocal.scala:84: diverging implicit expansion for type slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel, Nothing, T, G]
[error] starting with method repColumnShape in trait RepShapeImplicits
[error] .map { case (u, (uc, c)) => (u, c.optionProjection) }
关于此代码:
def getContentsByUser(userId: UUID): Either[UserNotFoundError, List[Content]] = {
val subQuery =
for {
uc <- UserContentTable.query if uc.userId === userId.toString && (!uc.adopted.isDefined || !uc.adopted)
c <- ContentTable.query if uc.contentId === c.id
} yield (uc, c)
val query =
UserTable.query.filter(_.id === userId.toString)
.joinLeft(subQuery).on { case (u, (uc, c)) => u.id === uc.userId}
.map { case (u, (uc, c)) => (u, c.optionProjection) }
//...
}
编辑 1:
通过重构我的子查询以使用 for
理解语法,进一步了解了这一点:
val query =
for (
(u, t) <- UserTable.query.filter(_.id === userId.toString) joinLeft subQuery on { case (u, (uc, c)) => u.id === uc.userId }
) yield (u, t)
编译通过。但是,根据 documentation,yield
应该应用 t.map(_)
将 Null
值转换为 None
。
因此,当我将行重构为:
yield (u, t.map(_))
我收到错误:
[error] missing parameter type for expanded function ((x) => t.map(x))
[error] ) yield (u, t.map(_))
[error] ^
[error] one error found
编辑 2: 您可以找到一个最小的、完整的和可验证的示例 here。
编辑 3: 确认 Slick 3.1.1
中也存在此问题
joinLeft
在 Slick3 中加入 subQuery
作为 Option
。在这种情况下,您必须按如下方式重新映射 subQuery
:
val query =
UserTable.query.filter(_.id === userId.toString)
.joinLeft(subQuery).on { case (u, (uc, c)) => u.id === uc.userId}
.map { case (u, sub) => (u, sub.map { case (uc, c) => c }) }
我正在将一些代码从 Slick 2.1 转换到 3.0.3,当我将我的连接从使用 leftJoin
迁移到 joinLeft
时,我收到了这个错误,我不确定如何解决:
[error] ContentRepoLocal.scala:84: constructor cannot be instantiated to expected type;
[error] found : (T1, T2)
[error] required: slick.lifted.Rep[Option[(repo.model.UserContentTable, repo.model.ContentTable)]]
[error] .map { case (u, (uc, c)) => (u, c.optionProjection) }
[error] ^
[error] ContentRepoLocal.scala:84: diverging implicit expansion for type slick.lifted.Shape[_ <: slick.lifted.FlatShapeLevel, Nothing, T, G]
[error] starting with method repColumnShape in trait RepShapeImplicits
[error] .map { case (u, (uc, c)) => (u, c.optionProjection) }
关于此代码:
def getContentsByUser(userId: UUID): Either[UserNotFoundError, List[Content]] = {
val subQuery =
for {
uc <- UserContentTable.query if uc.userId === userId.toString && (!uc.adopted.isDefined || !uc.adopted)
c <- ContentTable.query if uc.contentId === c.id
} yield (uc, c)
val query =
UserTable.query.filter(_.id === userId.toString)
.joinLeft(subQuery).on { case (u, (uc, c)) => u.id === uc.userId}
.map { case (u, (uc, c)) => (u, c.optionProjection) }
//...
}
编辑 1:
通过重构我的子查询以使用 for
理解语法,进一步了解了这一点:
val query =
for (
(u, t) <- UserTable.query.filter(_.id === userId.toString) joinLeft subQuery on { case (u, (uc, c)) => u.id === uc.userId }
) yield (u, t)
编译通过。但是,根据 documentation,yield
应该应用 t.map(_)
将 Null
值转换为 None
。
因此,当我将行重构为:
yield (u, t.map(_))
我收到错误:
[error] missing parameter type for expanded function ((x) => t.map(x))
[error] ) yield (u, t.map(_))
[error] ^
[error] one error found
编辑 2: 您可以找到一个最小的、完整的和可验证的示例 here。
编辑 3: 确认 Slick 3.1.1
中也存在此问题
joinLeft
在 Slick3 中加入 subQuery
作为 Option
。在这种情况下,您必须按如下方式重新映射 subQuery
:
val query =
UserTable.query.filter(_.id === userId.toString)
.joinLeft(subQuery).on { case (u, (uc, c)) => u.id === uc.userId}
.map { case (u, sub) => (u, sub.map { case (uc, c) => c }) }